2015-02-11 16:18:18 +11:00
|
|
|
/*
|
2015-04-13 18:05:28 +10:00
|
|
|
* 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
|
2015-02-11 16:18:18 +11:00
|
|
|
*
|
2015-04-13 18:05:28 +10:00
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
2015-02-11 16:18:18 +11:00
|
|
|
*
|
2015-04-13 18:05:28 +10:00
|
|
|
* 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.
|
2015-02-11 16:18:18 +11:00
|
|
|
*
|
2017-12-15 18:57:10 +11:00
|
|
|
* Copyright 2015, 2017 Danny Robson <danny@nerdcruft.net>
|
2015-02-11 16:18:18 +11:00
|
|
|
*/
|
|
|
|
|
2015-02-09 17:43:24 +11:00
|
|
|
|
2017-12-15 18:57:10 +11:00
|
|
|
#ifndef CRUFT_UTIL_URI_HPP
|
|
|
|
#define CRUFT_UTIL_URI_HPP
|
2015-02-09 17:43:24 +11:00
|
|
|
|
2018-01-10 17:19:39 +11:00
|
|
|
#include "debug.hpp"
|
2015-02-11 16:18:43 +11:00
|
|
|
#include "view.hpp"
|
|
|
|
|
2017-12-15 18:57:10 +11:00
|
|
|
#include <array>
|
2015-02-09 17:43:24 +11:00
|
|
|
#include <string>
|
|
|
|
#include <stdexcept>
|
|
|
|
|
|
|
|
|
|
|
|
namespace util {
|
2017-12-15 18:57:10 +11:00
|
|
|
// parsing of rfc3986 uniform resource identifiers
|
|
|
|
//
|
|
|
|
// does not currently perform normalisation (scheme or protocol),
|
|
|
|
// comparison, or other associated operations. though these should be
|
|
|
|
// added in the future.
|
|
|
|
//
|
|
|
|
// note that the parsed results may not always conform to expectations
|
|
|
|
// for some protocols. eg, mailto identifiers are complex to parse
|
|
|
|
// reliably and would require a specialised parser to be reliable.
|
|
|
|
//
|
|
|
|
// not all fields will be present for all protocols (or all instances of
|
|
|
|
// any given protocol). eg, the "tel" is unlikely to have port numbers.
|
2015-02-09 17:43:24 +11:00
|
|
|
class uri {
|
|
|
|
public:
|
2015-06-04 22:18:43 +10:00
|
|
|
explicit uri (std::string &&);
|
2017-12-26 17:33:06 +11:00
|
|
|
explicit uri (const std::string&);
|
2018-01-13 13:48:58 +11:00
|
|
|
explicit uri (const char *);
|
2017-12-26 17:33:06 +11:00
|
|
|
explicit uri (util::view<const char *>);
|
2015-02-09 17:43:24 +11:00
|
|
|
|
|
|
|
class parse_error : public std::runtime_error
|
|
|
|
{ using runtime_error::runtime_error; };
|
|
|
|
|
2017-12-15 18:57:10 +11:00
|
|
|
|
|
|
|
// URI: 'https://user:password@example.com:80/path/to?foo=bar#fragment'
|
|
|
|
//
|
|
|
|
// SCHEME: 'https'
|
|
|
|
// HIERARCHICAL: 'user:password@example.com:80/path/to'
|
|
|
|
// AUTHORITY: 'user:password@example.com:80'
|
|
|
|
// USER: 'user:password'
|
|
|
|
// HOST: 'example.com'
|
|
|
|
// PORT: '80'
|
|
|
|
// PATH: '/path/to'
|
|
|
|
// QUERY: 'foo=bar'
|
|
|
|
// FRAGMENT: 'fragment'
|
2016-05-12 17:39:33 +10:00
|
|
|
enum component {
|
2015-02-09 17:43:24 +11:00
|
|
|
SCHEME,
|
2017-12-15 18:57:10 +11:00
|
|
|
HIERARCHICAL,
|
|
|
|
AUTHORITY,
|
|
|
|
USER,
|
|
|
|
HOST,
|
|
|
|
PORT,
|
|
|
|
PATH,
|
2015-02-09 17:43:24 +11:00
|
|
|
QUERY,
|
|
|
|
FRAGMENT,
|
|
|
|
|
|
|
|
NUM_COMPONENTS
|
|
|
|
};
|
|
|
|
|
2017-12-26 17:33:24 +11:00
|
|
|
view<const char*>
|
|
|
|
get (component c) const&
|
|
|
|
{
|
|
|
|
CHECK_LIMIT (c, 0, NUM_COMPONENTS);
|
|
|
|
return m_views[c];
|
|
|
|
}
|
|
|
|
|
|
|
|
util::view<const char*> all (void) const& { return util::make_view (m_value); }
|
|
|
|
|
|
|
|
util::view<const char*> scheme (void) const& { return get (SCHEME); }
|
|
|
|
util::view<const char*> heirarchical (void) const& { return get (HIERARCHICAL); }
|
|
|
|
util::view<const char*> authority (void) const& { return get (AUTHORITY); }
|
|
|
|
util::view<const char*> user (void) const& { return get (USER); }
|
|
|
|
util::view<const char*> host (void) const& { return get (HOST); }
|
|
|
|
util::view<const char*> port (void) const& { return get (PORT); }
|
|
|
|
util::view<const char*> path (void) const& { return get (PATH); }
|
|
|
|
util::view<const char*> query (void) const& { return get (QUERY); }
|
|
|
|
util::view<const char*> fragment (void) const& { return get (FRAGMENT); }
|
|
|
|
|
|
|
|
auto components (void) const& noexcept { return m_views; }
|
2015-02-09 17:43:24 +11:00
|
|
|
|
2015-09-21 15:36:05 +10:00
|
|
|
static std::string percent_decode (view<const char*>);
|
2015-02-09 17:43:24 +11:00
|
|
|
|
|
|
|
private:
|
2017-12-15 18:57:10 +11:00
|
|
|
std::array<view<const char*>, NUM_COMPONENTS> m_views;
|
2015-02-09 17:43:24 +11:00
|
|
|
std::string m_value;
|
|
|
|
};
|
|
|
|
|
|
|
|
std::ostream& operator<< (std::ostream&, uri::component);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|