/*** * Copyright (C) Microsoft. All rights reserved. * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. * * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ * * Builder style class for creating URIs. * * For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk * * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ****/ #pragma once #include "cpprest/base_uri.h" #include namespace web { /// /// Builder for constructing URIs incrementally. /// class uri_builder { public: /// /// Creates a builder with an initially empty URI. /// uri_builder() = default; /// /// Creates a builder with a existing URI object. /// /// Encoded string containing the URI. uri_builder(const uri& uri_str) : m_uri(uri_str.m_components) {} /// /// Get the scheme component of the URI as an encoded string. /// /// The URI scheme as a string. const utility::string_t& scheme() const { return m_uri.m_scheme; } /// /// Get the user information component of the URI as an encoded string. /// /// The URI user information as a string. const utility::string_t& user_info() const { return m_uri.m_user_info; } /// /// Get the host component of the URI as an encoded string. /// /// The URI host as a string. const utility::string_t& host() const { return m_uri.m_host; } /// /// Get the port component of the URI. Returns -1 if no port is specified. /// /// The URI port as an integer. int port() const { return m_uri.m_port; } /// /// Get the path component of the URI as an encoded string. /// /// The URI path as a string. const utility::string_t& path() const { return m_uri.m_path; } /// /// Get the query component of the URI as an encoded string. /// /// The URI query as a string. const utility::string_t& query() const { return m_uri.m_query; } /// /// Get the fragment component of the URI as an encoded string. /// /// The URI fragment as a string. const utility::string_t& fragment() const { return m_uri.m_fragment; } /// /// Set the scheme of the URI. /// /// Uri scheme. /// A reference to this uri_builder to support chaining. uri_builder& set_scheme(const utility::string_t& scheme) { m_uri.m_scheme = scheme; return *this; } /// /// Set the user info component of the URI. /// /// User info as a decoded string. /// Specify whether to apply URI encoding to the given string. /// A reference to this uri_builder to support chaining. uri_builder& set_user_info(const utility::string_t& user_info, bool do_encoding = false) { if (do_encoding) { m_uri.m_user_info = uri::encode_uri(user_info, uri::components::user_info); } else { m_uri.m_user_info = user_info; } return *this; } /// /// Set the host component of the URI. /// /// Host as a decoded string. /// Specify whether to apply URI encoding to the given string. /// A reference to this uri_builder to support chaining. uri_builder& set_host(const utility::string_t& host, bool do_encoding = false) { if (do_encoding) { m_uri.m_host = uri::encode_uri(host, uri::components::host); } else { m_uri.m_host = host; } return *this; } /// /// Set the port component of the URI. /// /// Port as an integer. /// A reference to this uri_builder to support chaining. uri_builder& set_port(int port) { m_uri.m_port = port; return *this; } /// /// Set the port component of the URI. /// /// Port as a string. /// A reference to this uri_builder to support chaining. /// When string can't be converted to an integer the port is left unchanged. _ASYNCRTIMP uri_builder& set_port(const utility::string_t& port); /// /// Set the path component of the URI. /// /// Path as a decoded string. /// Specify whether to apply URI encoding to the given string. /// A reference to this uri_builder to support chaining. uri_builder& set_path(const utility::string_t& path, bool do_encoding = false) { if (do_encoding) { m_uri.m_path = uri::encode_uri(path, uri::components::path); } else { m_uri.m_path = path; } return *this; } /// /// Set the query component of the URI. /// /// Query as a decoded string. /// Specify whether apply URI encoding to the given string. /// A reference to this uri_builder to support chaining. uri_builder& set_query(const utility::string_t& query, bool do_encoding = false) { if (do_encoding) { m_uri.m_query = uri::encode_uri(query, uri::components::query); } else { m_uri.m_query = query; } return *this; } /// /// Set the fragment component of the URI. /// /// Fragment as a decoded string. /// Specify whether to apply URI encoding to the given string. /// A reference to this uri_builder to support chaining. uri_builder& set_fragment(const utility::string_t& fragment, bool do_encoding = false) { if (do_encoding) { m_uri.m_fragment = uri::encode_uri(fragment, uri::components::fragment); } else { m_uri.m_fragment = fragment; } return *this; } /// /// Clears all components of the underlying URI in this uri_builder. /// void clear() { m_uri = details::uri_components(); } /// /// Appends another path to the path of this uri_builder. /// /// Path to append as a already encoded string. /// Specify whether to apply URI encoding to the given string. /// A reference to this uri_builder to support chaining. _ASYNCRTIMP uri_builder& append_path(const utility::string_t& path, bool do_encoding = false); /// /// Appends the raw contents of the path argument to the path of this uri_builder with no separator de-duplication. /// /// /// The path argument is appended after adding a '/' separator without regards to the contents of path. If an empty /// string is provided, this function will immediately return without changes to the stored path value. For example: /// if the current contents are "/abc" and path="/xyz", the result will be "/abc//xyz". /// /// Path to append as a already encoded string. /// Specify whether to apply URI encoding to the given string. /// A reference to this uri_builder to support chaining. _ASYNCRTIMP uri_builder& append_path_raw(const utility::string_t& path, bool do_encoding = false); /// /// Appends another query to the query of this uri_builder. /// /// Query to append as a decoded string. /// Specify whether to apply URI encoding to the given string. /// A reference to this uri_builder to support chaining. _ASYNCRTIMP uri_builder& append_query(const utility::string_t& query, bool do_encoding = false); /// /// Appends an relative uri (Path, Query and fragment) at the end of the current uri. /// /// The relative uri to append. /// A reference to this uri_builder to support chaining. _ASYNCRTIMP uri_builder& append(const uri& relative_uri); /// /// 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. /// /// The name portion of the query string /// The value portion of the query string /// A reference to this uri_builder to support chaining. template uri_builder& append_query(const utility::string_t& name, const T& value, bool do_encoding = true) { if (do_encoding) append_query_encode_impl(name, utility::conversions::details::print_utf8string(value)); else append_query_no_encode_impl(name, utility::conversions::details::print_string(value)); return *this; } /// /// Combine and validate the URI components into a encoded string. An exception will be thrown if the URI is /// invalid. /// /// The created URI as a string. _ASYNCRTIMP utility::string_t to_string() const; /// /// Combine and validate the URI components into a URI class instance. An exception will be thrown if the URI is /// invalid. /// /// The create URI as a URI class instance. _ASYNCRTIMP uri to_uri() const; /// /// Validate the generated URI from all existing components of this uri_builder. /// /// Whether the URI is valid. _ASYNCRTIMP bool is_valid(); private: _ASYNCRTIMP void append_query_encode_impl(const utility::string_t& name, const utf8string& value); _ASYNCRTIMP void append_query_no_encode_impl(const utility::string_t& name, const utility::string_t& value); details::uri_components m_uri; }; } // namespace web