33// (See accompanying file LICENSE_1_0.txt or copy at
44// http://www.boost.org/LICENSE_1_0.txt)
55
6- #ifndef __TTP_NETWORK_HTTP_V2_URL_INC__
7- #define __HTTP_NETWORK_HTTP_V2_URL_INC__
6+ #ifndef __NETWORK_HTTP_V2_URL_INC__
7+ #define __NETWORK_HTTP_V2_URL_INC__
88
99#include < network/uri.hpp>
10+ #include < boost/range/algorithm/equal.hpp>
11+ #include < boost/range/as_literal.hpp>
1012
1113namespace network {
1214namespace http {
1315namespace v2 {
14- class invalid_scheme :public std ::runtime_error {
16+ class scheme_not_http :public std ::runtime_error {
1517
1618public:
1719
18- virtual ~invalid_scheme ()noexcept {}
19- virtual const char *what ()const noexcept {
20- return " invalid_scheme" ;
21- }
20+ scheme_not_http () : std::runtime_error(" scheme_not_http" ) {}
21+ virtual ~scheme_not_http ()noexcept {}
2222
2323 };
2424
@@ -34,19 +34,25 @@ namespace network {
3434
3535public:
3636
37- url () {
38-
37+ url () {}
38+
39+ template <class Source >
40+ url (const Source &source)
41+ : uri_(source) {
42+ if (auto scheme_ = uri_.scheme ()) {
43+ if (!boost::equal (boost::as_literal (" http" ), *scheme_) &&
44+ !boost::equal (boost::as_literal (" https" ), *scheme_) &&
45+ !boost::equal (boost::as_literal (" shttp" ), *scheme_)) {
46+ throw scheme_not_http ();
47+ }
48+ }
3949}
4050
4151url (const url &other)
42- : uri_(other.uri_) {
52+ : uri_(other.uri_) { }
4353
44- }
45-
46- url (url &&other)
47- : uri_(other.uri_) {
48-
49- }
54+ url (url &&other)noexcept
55+ : uri_(std::move(other.uri_)) { }
5056
5157url &operator = (url other) {
5258 other.swap (*this );
@@ -65,6 +71,38 @@ namespace network {
6571return uri_.end ();
6672}
6773
74+ boost::optional<string_view>user_info ()const {
75+ return uri_.user_info ();
76+ }
77+
78+ boost::optional<string_view>host ()const {
79+ return uri_.host ();
80+ }
81+
82+ boost::optional<string_view>port ()const {
83+ return uri_.port ();
84+ }
85+
86+ boost::optional<string_view>path ()const {
87+ return uri_.path ();
88+ }
89+
90+ boost::optional<string_view>query ()const {
91+ return uri_.query ();
92+ }
93+
94+ boost::optional<string_view>fragment ()const {
95+ return uri_.fragment ();
96+ }
97+
98+ boost::optional<string_view>authority ()const {
99+ return uri_.authority ();
100+ }
101+
102+ std::stringstring ()const {
103+ return uri_.string ();
104+ }
105+
68106bool empty ()const noexcept {
69107return uri_.empty ();
70108}
@@ -73,6 +111,31 @@ namespace network {
73111return uri_.is_absolute ();
74112}
75113
114+ urlnormalize (uri_comparison_level level)const {
115+ return url (uri_.normalize (level));
116+ // if scheme-specific
117+ // normalize query arguments in alphanumeric order
118+ }
119+
120+ urlmake_reference (const url &other, uri_comparison_level level)const {
121+ return url (uri_.make_reference (other.uri_ , level));
122+ }
123+
124+ urlresolve (const url &other, uri_comparison_level level)const {
125+ return url (uri_.resolve (other.uri_ , level));
126+ }
127+
128+ int compare (const url &other, uri_comparison_level level)const noexcept {
129+ int result = uri_.compare (other.uri_ , level);
130+ // if result == 0 and scheme-specific
131+ // compare query arguments
132+ return result;
133+ }
134+
135+ urito_uri ()const {
136+ return uri_;
137+ }
138+
76139private:
77140
78141uri uri_;
@@ -82,5 +145,4 @@ namespace network {
82145 }// namespace http
83146}// namespace network
84147
85-
86- #endif // __HTTP_NETWORK_HTTP_V2_URL_INC__
148+ #endif // __NETWORK_HTTP_V2_URL_INC__