/*** * ==++== * * 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 #include #include #include "cpprest/base_uri.h" namespace web { /// /// Builder for constructing URIs incrementally. /// class uri_builder { public: /// /// Creates a builder with an initially empty URI. /// uri_builder() {} /// /// 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) { m_uri.m_user_info = do_encoding ? uri::encode_uri(user_info, uri::components::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) { m_uri.m_host = do_encoding ? uri::encode_uri(host, uri::components::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. 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; } /// /// 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) { m_uri.m_path = do_encoding ? uri::encode_uri(path, uri::components::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) { m_uri.m_query = do_encoding ? uri::encode_uri(query, uri::components::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) { m_uri.m_fragment = do_encoding ? uri::encode_uri(fragment, uri::components::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 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(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); } /// /// 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(); /// /// 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(); /// /// Validate the generated URI from all existing components of this uri_builder. /// /// Whether the URI is valid. _ASYNCRTIMP bool is_valid(); private: details::uri_components m_uri; }; } // namespace web