266 lines
11 KiB
C++
266 lines
11 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.
|
|
*
|
|
* ==--==
|
|
* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
|
*
|
|
* Builder style class for creating URIs.
|
|
*
|
|
* For the latest on this and related APIs, please see http://casablanca.codeplex.com.
|
|
*
|
|
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
****/
|
|
|
|
#pragma once
|
|
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "cpprest/base_uri.h"
|
|
|
|
namespace web
|
|
{
|
|
/// <summary>
|
|
/// Builder for constructing URIs incrementally.
|
|
/// </summary>
|
|
class uri_builder
|
|
{
|
|
public:
|
|
|
|
/// <summary>
|
|
/// Creates a builder with an initially empty URI.
|
|
/// </summary>
|
|
uri_builder() {}
|
|
|
|
/// <summary>
|
|
/// Creates a builder with a existing URI object.
|
|
/// </summary>
|
|
/// <param name="uri_str">Encoded string containing the URI.</param>
|
|
uri_builder(const uri &uri_str): m_uri(uri_str.m_components) {}
|
|
|
|
/// <summary>
|
|
/// Get the scheme component of the URI as an encoded string.
|
|
/// </summary>
|
|
/// <returns>The URI scheme as a string.</returns>
|
|
const utility::string_t &scheme() const { return m_uri.m_scheme; }
|
|
|
|
/// <summary>
|
|
/// Get the user information component of the URI as an encoded string.
|
|
/// </summary>
|
|
/// <returns>The URI user information as a string.</returns>
|
|
const utility::string_t &user_info() const { return m_uri.m_user_info; }
|
|
|
|
/// <summary>
|
|
/// Get the host component of the URI as an encoded string.
|
|
/// </summary>
|
|
/// <returns>The URI host as a string.</returns>
|
|
const utility::string_t &host() const { return m_uri.m_host; }
|
|
|
|
/// <summary>
|
|
/// Get the port component of the URI. Returns -1 if no port is specified.
|
|
/// </summary>
|
|
/// <returns>The URI port as an integer.</returns>
|
|
int port() const { return m_uri.m_port; }
|
|
|
|
/// <summary>
|
|
/// Get the path component of the URI as an encoded string.
|
|
/// </summary>
|
|
/// <returns>The URI path as a string.</returns>
|
|
const utility::string_t &path() const { return m_uri.m_path; }
|
|
|
|
/// <summary>
|
|
/// Get the query component of the URI as an encoded string.
|
|
/// </summary>
|
|
/// <returns>The URI query as a string.</returns>
|
|
const utility::string_t &query() const { return m_uri.m_query; }
|
|
|
|
/// <summary>
|
|
/// Get the fragment component of the URI as an encoded string.
|
|
/// </summary>
|
|
/// <returns>The URI fragment as a string.</returns>
|
|
const utility::string_t &fragment() const { return m_uri.m_fragment; }
|
|
|
|
/// <summary>
|
|
/// Set the scheme of the URI.
|
|
/// </summary>
|
|
/// <param name="scheme">Uri scheme.</param>
|
|
/// <returns>A reference to this <c>uri_builder</c> to support chaining.</returns>
|
|
uri_builder & set_scheme(const utility::string_t &scheme)
|
|
{
|
|
m_uri.m_scheme = scheme;
|
|
return *this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the user info component of the URI.
|
|
/// </summary>
|
|
/// <param name="user_info">User info as a decoded string.</param>
|
|
/// <param name="do_encoding">Specify whether to apply URI encoding to the given string.</param>
|
|
/// <returns>A reference to this <c>uri_builder</c> to support chaining.</returns>
|
|
uri_builder & set_user_info(const utility::string_t &user_info, bool do_encoding = false)
|
|
{
|
|
m_uri.m_user_info = do_encoding ? uri::encode_uri(user_info, uri::components::user_info) : user_info;
|
|
return *this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the host component of the URI.
|
|
/// </summary>
|
|
/// <param name="host">Host as a decoded string.</param>
|
|
/// <param name="do_encoding">Specify whether to apply URI encoding to the given string.</param>
|
|
/// <returns>A reference to this <c>uri_builder</c> to support chaining.</returns>
|
|
uri_builder & set_host(const utility::string_t &host, bool do_encoding = false)
|
|
{
|
|
m_uri.m_host = do_encoding ? uri::encode_uri(host, uri::components::host) : host;
|
|
return *this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the port component of the URI.
|
|
/// </summary>
|
|
/// <param name="port">Port as an integer.</param>
|
|
/// <returns>A reference to this <c>uri_builder</c> to support chaining.</returns>
|
|
uri_builder & set_port(int port)
|
|
{
|
|
m_uri.m_port = port;
|
|
return *this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the port component of the URI.
|
|
/// </summary>
|
|
/// <param name="port">Port as a string.</param>
|
|
/// <returns>A reference to this <c>uri_builder</c> to support chaining.</returns>
|
|
/// <remarks>When string can't be converted to an integer the port is left unchanged.</remarks>
|
|
uri_builder & set_port(const utility::string_t &port)
|
|
{
|
|
utility::istringstream_t portStream(port);
|
|
int port_tmp;
|
|
portStream >> port_tmp;
|
|
if(portStream.fail() || portStream.bad())
|
|
{
|
|
throw std::invalid_argument("invalid port argument, must be non empty string containing integer value");
|
|
}
|
|
m_uri.m_port = port_tmp;
|
|
return *this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the path component of the URI.
|
|
/// </summary>
|
|
/// <param name="path">Path as a decoded string.</param>
|
|
/// <param name="do_encoding">Specify whether to apply URI encoding to the given string.</param>
|
|
/// <returns>A reference to this <c>uri_builder</c> to support chaining.</returns>
|
|
uri_builder & set_path(const utility::string_t &path, bool do_encoding = false)
|
|
{
|
|
m_uri.m_path = do_encoding ? uri::encode_uri(path, uri::components::path) : path;
|
|
return *this;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Set the query component of the URI.
|
|
/// </summary>
|
|
/// <param name="query">Query as a decoded string.</param>
|
|
/// <param name="do_encoding">Specify whether apply URI encoding to the given string.</param>
|
|
/// <returns>A reference to this <c>uri_builder</c> to support chaining.</returns>
|
|
uri_builder & set_query(const utility::string_t &query, bool do_encoding = false)
|
|
{
|
|
m_uri.m_query = do_encoding ? uri::encode_uri(query, uri::components::query) : query;
|
|
return *this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the fragment component of the URI.
|
|
/// </summary>
|
|
/// <param name="fragment">Fragment as a decoded string.</param>
|
|
/// <param name="do_encoding">Specify whether to apply URI encoding to the given string.</param>
|
|
/// <returns>A reference to this <c>uri_builder</c> to support chaining.</returns>
|
|
uri_builder & set_fragment(const utility::string_t &fragment, bool do_encoding = false)
|
|
{
|
|
m_uri.m_fragment = do_encoding ? uri::encode_uri(fragment, uri::components::fragment) : fragment;
|
|
return *this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clears all components of the underlying URI in this uri_builder.
|
|
/// </summary>
|
|
void clear()
|
|
{
|
|
m_uri = details::uri_components();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Appends another path to the path of this uri_builder.
|
|
/// </summary>
|
|
/// <param name="path">Path to append as a already encoded string.</param>
|
|
/// <param name="do_encoding">Specify whether to apply URI encoding to the given string.</param>
|
|
/// <returns>A reference to this uri_builder to support chaining.</returns>
|
|
_ASYNCRTIMP uri_builder &append_path(const utility::string_t &path, bool do_encoding = false);
|
|
|
|
/// <summary>
|
|
/// Appends another query to the query of this uri_builder.
|
|
/// </summary>
|
|
/// <param name="query">Query to append as a decoded string.</param>
|
|
/// <param name="do_encoding">Specify whether to apply URI encoding to the given string.</param>
|
|
/// <returns>A reference to this uri_builder to support chaining.</returns>
|
|
_ASYNCRTIMP uri_builder &append_query(const utility::string_t &query, bool do_encoding = false);
|
|
|
|
/// <summary>
|
|
/// Appends an relative uri (Path, Query and fragment) at the end of the current uri.
|
|
/// </summary>
|
|
/// <param name="relative_uri">The relative uri to append.</param>
|
|
/// <returns>A reference to this uri_builder to support chaining.</returns>
|
|
_ASYNCRTIMP uri_builder &append(const uri &relative_uri);
|
|
|
|
/// <summary>
|
|
/// Appends another query to the query of this uri_builder, encoding it first. This overload is useful when building a query segment of
|
|
/// the form "element=10", where the right hand side of the query is stored as a type other than a string, for instance, an integral type.
|
|
/// </summary>
|
|
/// <param name="name">The name portion of the query string</param>
|
|
/// <param name="value">The value portion of the query string</param>
|
|
/// <returns>A reference to this uri_builder to support chaining.</returns>
|
|
template<typename T>
|
|
uri_builder &append_query(utility::string_t name, const T &value, bool do_encoding = true)
|
|
{
|
|
utility::ostringstream_t ss;
|
|
ss.imbue(std::locale::classic());
|
|
ss << name << _XPLATSTR("=") << value;
|
|
return append_query(ss.str(), do_encoding);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Combine and validate the URI components into a encoded string. An exception will be thrown if the URI is invalid.
|
|
/// </summary>
|
|
/// <returns>The created URI as a string.</returns>
|
|
_ASYNCRTIMP utility::string_t to_string();
|
|
|
|
/// <summary>
|
|
/// Combine and validate the URI components into a URI class instance. An exception will be thrown if the URI is invalid.
|
|
/// </summary>
|
|
/// <returns>The create URI as a URI class instance.</returns>
|
|
_ASYNCRTIMP uri to_uri();
|
|
|
|
/// <summary>
|
|
/// Validate the generated URI from all existing components of this uri_builder.
|
|
/// </summary>
|
|
/// <returns>Whether the URI is valid.</returns>
|
|
_ASYNCRTIMP bool is_valid();
|
|
|
|
private:
|
|
details::uri_components m_uri;
|
|
};
|
|
} // namespace web
|