From 90c80c6f7e5a87b56ea0cd2f7007697c963cc109 Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Wed, 11 May 2016 07:24:13 +0200 Subject: [PATCH 1/3] Tried to address awkward API issue when append query parameters. --- include/network/uri/uri_builder.hpp | 8 +- src/uri_builder.cpp | 11 ++- test/uri_builder_test.cpp | 132 +++++++++++++++------------- test/uri_resolve_test.cpp | 18 ++-- 4 files changed, 92 insertions(+), 77 deletions(-) diff --git a/include/network/uri/uri_builder.hpp b/include/network/uri/uri_builder.hpp index 80fce8ca..fd73e30e 100644 --- a/include/network/uri/uri_builder.hpp +++ b/include/network/uri/uri_builder.hpp @@ -187,8 +187,8 @@ class uri_builder { * \returns \c *this */ template - uri_builder &query(const Source &query) { - set_query(detail::translate(query)); + uri_builder &append_query(const Source &query) { + append_query(detail::translate(query)); return *this; } @@ -205,7 +205,7 @@ class uri_builder { * \returns \c *this */ template - uri_builder &query(const Key &key, const Value &value) { + uri_builder &append_query_key_value_pair(const Key &key, const Value &value) { if (!query_) { query_ = string_type(); } @@ -252,7 +252,7 @@ class uri_builder { void set_port(string_type port); void set_authority(string_type authority); void set_path(string_type path); - void set_query(string_type query); + void append_query(string_type query); void set_fragment(string_type fragment); optional scheme_, user_info_, host_, port_, path_, query_, diff --git a/src/uri_builder.cpp b/src/uri_builder.cpp index 175d13b0..e10038d3 100644 --- a/src/uri_builder.cpp +++ b/src/uri_builder.cpp @@ -32,7 +32,7 @@ uri_builder::uri_builder(const network::uri &base_uri) { } if (base_uri.has_query()) { - set_query(base_uri.query().to_string()); + append_query(base_uri.query().to_string()); } if (base_uri.has_fragment()) { @@ -111,8 +111,13 @@ uri_builder &uri_builder::clear_path() { return *this; } -void uri_builder::set_query(string_type query) { - query_ = string_type(); +void uri_builder::append_query(string_type query) { + if (!query_) { + query_ = string_type(); + } + else { + query_->append("&"); + } network::uri::encode_query(std::begin(query), std::end(query), std::back_inserter(*query_)); } diff --git a/test/uri_builder_test.cpp b/test/uri_builder_test.cpp index 87345802..0ba170c3 100644 --- a/test/uri_builder_test.cpp +++ b/test/uri_builder_test.cpp @@ -36,7 +36,7 @@ TEST(builder_test, simple_uri) { .host("www.example.com") .path("/") ; - ASSERT_EQ("http://www.example.com/", builder.uri()); + ASSERT_EQ("http://www.example.com/", builder.uri().string()); } TEST(builder_test, simple_uri_has_scheme) { @@ -154,7 +154,7 @@ TEST(builder_test, simple_opaque_uri) { .scheme("mailto") .path("john.doe@example.com") ; - ASSERT_EQ("mailto:john.doe@example.com", builder.uri()); + ASSERT_EQ("mailto:john.doe@example.com", builder.uri().string()); } TEST(builder_test, simple_opaque_uri_has_scheme) { @@ -190,7 +190,7 @@ TEST(builder_test, relative_hierarchical_uri) { .host("www.example.com") .path("/") ; - ASSERT_EQ("www.example.com/", builder.uri()); + ASSERT_EQ("www.example.com/", builder.uri().string()); } TEST(builder_test, relative_opaque_uri_doesnt_throw) { @@ -206,7 +206,7 @@ TEST(builder_test, relative_opaque_uri) { builder .path("john.doe@example.com") ; - ASSERT_EQ("john.doe@example.com", builder.uri()); + ASSERT_EQ("john.doe@example.com", builder.uri().string()); } TEST(builder_test, full_uri_doesnt_throw) { @@ -217,7 +217,7 @@ TEST(builder_test, full_uri_doesnt_throw) { .host("www.example.com") .port("80") .path("/path") - .query("query") + .append_query("query") .fragment("fragment") ; ASSERT_NO_THROW(builder.uri()); @@ -231,10 +231,10 @@ TEST(builder_test, full_uri) { .host("www.example.com") .port("80") .path("/path") - .query("query") + .append_query("query") .fragment("fragment") ; - ASSERT_EQ("http://user@www.example.com:80/path?query#fragment", builder.uri()); + ASSERT_EQ("http://user@www.example.com:80/path?query#fragment", builder.uri().string()); } TEST(builder_test, full_uri_has_scheme) { @@ -245,7 +245,7 @@ TEST(builder_test, full_uri_has_scheme) { .host("www.example.com") .port("80") .path("/path") - .query("query") + .append_query("query") .fragment("fragment") ; ASSERT_TRUE(builder.uri().has_scheme()); @@ -259,7 +259,7 @@ TEST(builder_test, full_uri_scheme_value) { .host("www.example.com") .port("80") .path("/path") - .query("query") + .append_query("query") .fragment("fragment") ; ASSERT_EQ("http", builder.uri().scheme()); @@ -273,7 +273,7 @@ TEST(builder_test, full_uri_has_user_info) { .host("www.example.com") .port("80") .path("/path") - .query("query") + .append_query("query") .fragment("fragment") ; ASSERT_TRUE(builder.uri().has_user_info()); @@ -287,7 +287,7 @@ TEST(builder_test, full_uri_user_info_value) { .host("www.example.com") .port("80") .path("/path") - .query("query") + .append_query("query") .fragment("fragment") ; ASSERT_EQ("user", builder.uri().user_info()); @@ -301,7 +301,7 @@ TEST(builder_test, full_uri_has_host) { .host("www.example.com") .port("80") .path("/path") - .query("query") + .append_query("query") .fragment("fragment") ; ASSERT_TRUE(builder.uri().has_host()); @@ -315,7 +315,7 @@ TEST(builder_test, full_uri_host_value) { .host("www.example.com") .port("80") .path("/path") - .query("query") + .append_query("query") .fragment("fragment") ; ASSERT_EQ("www.example.com", builder.uri().host()); @@ -329,7 +329,7 @@ TEST(builder_test, full_uri_has_port) { .host("www.example.com") .port("80") .path("/path") - .query("query") + .append_query("query") .fragment("fragment") ; ASSERT_TRUE(builder.uri().has_port()); @@ -343,7 +343,7 @@ TEST(builder_test, full_uri_has_path) { .host("www.example.com") .port("80") .path("/path") - .query("query") + .append_query("query") .fragment("fragment") ; ASSERT_TRUE(builder.uri().has_path()); @@ -357,7 +357,7 @@ TEST(builder_test, full_uri_path_value) { .host("www.example.com") .port("80") .path("/path") - .query("query") + .append_query("query") .fragment("fragment") ; ASSERT_EQ("/path", builder.uri().path()); @@ -371,7 +371,7 @@ TEST(builder_test, full_uri_has_query) { .host("www.example.com") .port("80") .path("/path") - .query("query") + .append_query("query") .fragment("fragment") ; ASSERT_TRUE(builder.uri().has_query()); @@ -385,7 +385,7 @@ TEST(builder_test, full_uri_query_value) { .host("www.example.com") .port("80") .path("/path") - .query("query") + .append_query("query") .fragment("fragment") ; ASSERT_EQ("query", builder.uri().query()); @@ -399,7 +399,7 @@ TEST(builder_test, full_uri_has_fragment) { .host("www.example.com") .port("80") .path("/path") - .query("query") + .append_query("query") .fragment("fragment") ; ASSERT_TRUE(builder.uri().has_fragment()); @@ -413,7 +413,7 @@ TEST(builder_test, full_uri_fragment_value) { .host("www.example.com") .port("80") .path("/path") - .query("query") + .append_query("query") .fragment("fragment") ; ASSERT_EQ("fragment", builder.uri().fragment()); @@ -425,7 +425,7 @@ TEST(builder_test, relative_uri) { .host("www.example.com") .path("/") ; - ASSERT_EQ("www.example.com/", builder.uri()); + ASSERT_EQ("www.example.com/", builder.uri().string()); } TEST(builder_test, relative_uri_scheme) { @@ -444,7 +444,7 @@ TEST(builder_test, authority) { .authority("www.example.com:8080") .path("/") ; - ASSERT_EQ("http://www.example.com:8080/", builder.uri()); + ASSERT_EQ("http://www.example.com:8080/", builder.uri().string()); ASSERT_EQ("www.example.com", builder.uri().host()); ASSERT_EQ("8080", builder.uri().port()); } @@ -489,7 +489,7 @@ TEST(builder_test, build_relative_uri_with_path_query_and_fragment) { network::uri_builder builder; builder .path("/path/") - .query("key", "value") + .append_query_key_value_pair("key", "value") .fragment("fragment") ; ASSERT_EQ("/path/", builder.uri().path()); @@ -504,7 +504,7 @@ TEST(builder_test, build_uri_with_capital_scheme) { .host("www.example.com") .path("/") ; - ASSERT_EQ("http://www.example.com/", builder.uri()); + ASSERT_EQ("http://www.example.com/", builder.uri().string()); } TEST(builder_test, build_uri_with_capital_host) { @@ -514,7 +514,7 @@ TEST(builder_test, build_uri_with_capital_host) { .host("WWW.EXAMPLE.COM") .path("/") ; - ASSERT_EQ("http://www.example.com/", builder.uri()); + ASSERT_EQ("http://www.example.com/", builder.uri().string()); } TEST(builder_test, build_uri_with_unencoded_path) { @@ -524,7 +524,7 @@ TEST(builder_test, build_uri_with_unencoded_path) { .host("www.example.com") .path("/A path with spaces") ; - ASSERT_EQ("http://www.example.com/A%20path%20with%20spaces", builder.uri()); + ASSERT_EQ("http://www.example.com/A%20path%20with%20spaces", builder.uri().string()); } TEST(builder_test, DISABLED_builder_uri_and_remove_dot_segments_from_path) { @@ -544,7 +544,7 @@ TEST(builder_test, build_uri_with_qmark_in_path) { .host("www.example.com") .path("/?/") ; - ASSERT_EQ("http://www.example.com/%3F/", builder.uri()); + ASSERT_EQ("http://www.example.com/%3F/", builder.uri().string()); } TEST(builder_test, build_uri_with_hash_in_path) { @@ -554,7 +554,7 @@ TEST(builder_test, build_uri_with_hash_in_path) { .host("www.example.com") .path("/#/") ; - ASSERT_EQ("http://www.example.com/%23/", builder.uri()); + ASSERT_EQ("http://www.example.com/%23/", builder.uri().string()); } TEST(builder_test, simple_port) { @@ -565,7 +565,7 @@ TEST(builder_test, simple_port) { .port(8000) .path("/") ; - ASSERT_EQ("http://www.example.com:8000/", builder.uri()); + ASSERT_EQ("http://www.example.com:8000/", builder.uri().string()); } TEST(builder_test, build_uri_with_query_item) { @@ -573,10 +573,10 @@ TEST(builder_test, build_uri_with_query_item) { builder .scheme("http") .host("www.example.com") - .query("a", "1") + .append_query_key_value_pair("a", "1") .path("/") ; - ASSERT_EQ("http://www.example.com/?a=1", builder.uri()); + ASSERT_EQ("http://www.example.com/?a=1", builder.uri().string()); } TEST(builder_test, build_uri_with_multiple_query_items) { @@ -584,11 +584,11 @@ TEST(builder_test, build_uri_with_multiple_query_items) { builder .scheme("http") .host("www.example.com") - .query("a", "1") - .query("b", "2") + .append_query_key_value_pair("a", "1") + .append_query_key_value_pair("b", "2") .path("/") ; - ASSERT_EQ("http://www.example.com/?a=1&b=2", builder.uri()); + ASSERT_EQ("http://www.example.com/?a=1&b=2", builder.uri().string()); } TEST(builder_test, build_uri_with_query_item_with_encoded_chars) @@ -597,10 +597,10 @@ TEST(builder_test, build_uri_with_query_item_with_encoded_chars) builder .scheme("http") .host("www.example.com") - .query("a", "parameter with encoded chars!") + .append_query_key_value_pair("a", "parameter with encoded chars!") .path("/") ; - ASSERT_EQ("http://www.example.com/?a=parameter%20with%20encoded%20chars%21", builder.uri()); + ASSERT_EQ("http://www.example.com/?a=parameter%20with%20encoded%20chars%21", builder.uri().string()); } TEST(builder_test, build_uri_with_multiple_query_items_with_encoded_chars) { @@ -608,36 +608,24 @@ TEST(builder_test, build_uri_with_multiple_query_items_with_encoded_chars) { builder .scheme("http") .host("www.example.com") - .query("a", "first parameter with encoded chars!") - .query("b", "second parameter with encoded chars!") + .append_query_key_value_pair("a", "first parameter with encoded chars!") + .append_query_key_value_pair("b", "second parameter with encoded chars!") .path("/") ; - ASSERT_EQ("http://www.example.com/?a=first%20parameter%20with%20encoded%20chars%21&b=second%20parameter%20with%20encoded%20chars%21", builder.uri()); + ASSERT_EQ("http://www.example.com/?a=first%20parameter%20with%20encoded%20chars%21&b=second%20parameter%20with%20encoded%20chars%21", builder.uri().string()); } -//TEST(builder_test, build_uri_with_multiple_query_items_with_int_values) { -// network::uri_builder builder; -// builder -// .scheme("http") -// .host("www.example.com") -// .query("a", 1) -// .query("b", 2) -// .path("/") -// ; -// ASSERT_EQ("http://www.example.com/?a=1&b=2", builder.uri()); -//} - TEST(builder_test, construct_from_existing_uri) { network::uri instance("http://www.example.com/"); network::uri_builder builder(instance); - ASSERT_EQ("http://www.example.com/", builder.uri()); + ASSERT_EQ("http://www.example.com/", builder.uri().string()); } TEST(builder_test, build_from_existing_uri) { network::uri instance("http://www.example.com/"); network::uri_builder builder(instance); - builder.query("a", "1").query("b", "2").fragment("fragment"); - ASSERT_EQ("http://www.example.com/?a=1&b=2#fragment", builder.uri()); + builder.append_query_key_value_pair("a", "1").append_query_key_value_pair("b", "2").fragment("fragment"); + ASSERT_EQ("http://www.example.com/?a=1&b=2#fragment", builder.uri().string()); } TEST(builder_test, authority_without_port_test) { @@ -671,49 +659,49 @@ TEST(builder_test, clear_user_info_test) { network::uri instance("http://user@www.example.com:80/path?query#fragment"); network::uri_builder builder(instance); builder.clear_user_info(); - ASSERT_EQ("http://www.example.com:80/path?query#fragment", builder.uri()); + ASSERT_EQ("http://www.example.com:80/path?query#fragment", builder.uri().string()); } TEST(builder_test, clear_port_test) { network::uri instance("http://user@www.example.com:80/path?query#fragment"); network::uri_builder builder(instance); builder.clear_port(); - ASSERT_EQ("http://user@www.example.com/path?query#fragment", builder.uri()); + ASSERT_EQ("http://user@www.example.com/path?query#fragment", builder.uri().string()); } TEST(builder_test, clear_path_test) { network::uri instance("http://user@www.example.com:80/path?query#fragment"); network::uri_builder builder(instance); builder.clear_path(); - ASSERT_EQ("http://user@www.example.com:80?query#fragment", builder.uri()); + ASSERT_EQ("http://user@www.example.com:80?query#fragment", builder.uri().string()); } TEST(builder_test, clear_query_test) { network::uri instance("http://user@www.example.com:80/path?query#fragment"); network::uri_builder builder(instance); builder.clear_query(); - ASSERT_EQ("http://user@www.example.com:80/path#fragment", builder.uri()); + ASSERT_EQ("http://user@www.example.com:80/path#fragment", builder.uri().string()); } TEST(builder_test, clear_fragment_test) { network::uri instance("http://user@www.example.com:80/path?query#fragment"); network::uri_builder builder(instance); builder.clear_fragment(); - ASSERT_EQ("http://user@www.example.com:80/path?query", builder.uri()); + ASSERT_EQ("http://user@www.example.com:80/path?query", builder.uri().string()); } TEST(builder_test, empty_username) { std::string user_info(":"); network::uri_builder builder; builder.scheme("ftp").host("127.0.0.1").user_info(user_info); - ASSERT_EQ("ftp://:@127.0.0.1", builder.uri()); + ASSERT_EQ("ftp://:@127.0.0.1", builder.uri().string()); } TEST(builder_test, path_should_be_prefixed_with_slash) { std::string path("relative"); network::uri_builder builder; builder.scheme("ftp").host("127.0.0.1").path(path); - ASSERT_EQ("ftp://127.0.0.1/relative", builder.uri()); + ASSERT_EQ("ftp://127.0.0.1/relative", builder.uri().string()); } TEST(builder_test, path_should_be_prefixed_with_slash_2) { @@ -722,3 +710,25 @@ TEST(builder_test, path_should_be_prefixed_with_slash_2) { .scheme("ftp").host("127.0.0.1").path("noleadingslash/foo.txt"); ASSERT_EQ("/noleadingslash/foo.txt", builder.uri().path()); } + +TEST(builder_test, set_multiple_query_with_encoding) { + network::uri_builder builder; + builder + .scheme("http") + .host("example.com") + .append_query("q1=foo bar") + .append_query("q2=biz baz") + ; + ASSERT_EQ("http://example.com?q1=foo%20bar&q2=biz%20baz", builder.uri().string()); +} + +TEST(builder_test, set_multiple_query_with_encoding_2) { + network::uri_builder builder; + builder + .scheme("http") + .host("example.com") + .append_query_key_value_pair("q1", "foo bar") + .append_query_key_value_pair("q2", "biz baz") + ; + ASSERT_EQ("http://example.com?q1=foo%20bar&q2=biz%20baz", builder.uri().string()); +} diff --git a/test/uri_resolve_test.cpp b/test/uri_resolve_test.cpp index 2ec21a6c..7c982c73 100644 --- a/test/uri_resolve_test.cpp +++ b/test/uri_resolve_test.cpp @@ -41,7 +41,7 @@ TEST_F(uri_resolve_test, base_has_empty_path__path_is_ref_path_1) TEST_F(uri_resolve_test, base_has_empty_path__path_is_ref_path_2) { - uri reference = uri_builder().path("g/x/y").query("q").fragment("s").uri(); + uri reference = uri_builder().path("g/x/y").append_query("q").fragment("s").uri(); ASSERT_EQ("http://a/g/x/y?q#s", resolved(uri("http://a/"), reference)); } @@ -69,7 +69,7 @@ TEST_F(uri_resolve_test, path_starts_with_slash__path_is_ref_path) { } TEST_F(uri_resolve_test, path_starts_with_slash_with_query_fragment__path_is_ref_path) { - uri reference = uri_builder().path("/g/x").query("y").fragment("s").uri(); + uri reference = uri_builder().path("/g/x").append_query("y").fragment("s").uri(); ASSERT_EQ("http://a/g/x?y#s", resolved(reference)); } @@ -81,17 +81,17 @@ TEST_F(uri_resolve_test, DISABLED_has_authority__base_scheme_with_ref_authority) } TEST_F(uri_resolve_test, path_is_empty_but_has_query__returns_base_with_ref_query) { - uri reference = uri_builder().query("y").uri(); + uri reference = uri_builder().append_query("y").uri(); ASSERT_EQ("http://a/b/c/d;p?y", resolved(reference)); } TEST_F(uri_resolve_test, path_is_empty_but_has_query_base_no_query__returns_base_with_ref_query) { - uri reference = uri_builder().query("y").uri(); + uri reference = uri_builder().append_query("y").uri(); ASSERT_EQ("http://a/b/c/d?y", resolved(uri("http://a/b/c/d"), reference)); } TEST_F(uri_resolve_test, merge_path_with_query) { - uri reference = uri_builder().path("g").query("y").uri(); + uri reference = uri_builder().path("g").append_query("y").uri(); ASSERT_EQ("http://a/b/c/g?y", resolved(reference)); } @@ -106,7 +106,7 @@ TEST_F(uri_resolve_test, merge_paths_with_fragment) { } TEST_F(uri_resolve_test, merge_paths_with_query_and_fragment) { - uri reference = uri_builder().path("g").query("y").fragment("s").uri(); + uri reference = uri_builder().path("g").append_query("y").fragment("s").uri(); ASSERT_EQ("http://a/b/c/g?y#s", resolved(reference)); } @@ -121,7 +121,7 @@ TEST_F(uri_resolve_test, merge_paths_with_semicolon_2) { } TEST_F(uri_resolve_test, merge_paths_with_semicolon_3) { - uri reference = uri_builder().path("g;x").query("y").fragment("s").uri(); + uri reference = uri_builder().path("g;x").append_query("y").fragment("s").uri(); ASSERT_EQ("http://a/b/c/g;x?y#s", resolved(reference)); } @@ -245,12 +245,12 @@ TEST_F(uri_resolve_test, abnormal_example_14) { } TEST_F(uri_resolve_test, abnormal_example_15) { - uri reference = uri_builder().path("g").query("y/./x").uri(); + uri reference = uri_builder().path("g").append_query("y/./x").uri(); ASSERT_EQ("http://a/b/c/g?y/./x", resolved(reference)); } TEST_F(uri_resolve_test, abnormal_example_16) { - uri reference = uri_builder().path("g").query("y/../x").uri(); + uri reference = uri_builder().path("g").append_query("y/../x").uri(); ASSERT_EQ("http://a/b/c/g?y/../x", resolved(reference)); } From 909763fe715707c628247cefee7dc32f76f7e384 Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Wed, 11 May 2016 07:24:13 +0200 Subject: [PATCH 2/3] Tried to address awkward API issue when append query parameters. --- test/uri_builder_test.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/test/uri_builder_test.cpp b/test/uri_builder_test.cpp index 9deecb9f..3525ad61 100644 --- a/test/uri_builder_test.cpp +++ b/test/uri_builder_test.cpp @@ -758,3 +758,25 @@ TEST(builder_test, non_const_non_array_string_literals_should_work) { ; ASSERT_EQ("http://example.com/foo", builder.uri()); } + +TEST(builder_test, set_multiple_query_with_encoding) { + network::uri_builder builder; + builder + .scheme("http") + .host("example.com") + .append_query("q1=foo bar") + .append_query("q2=biz baz") + ; + ASSERT_EQ("http://example.com?q1=foo%20bar&q2=biz%20baz", builder.uri().string()); +} + +TEST(builder_test, set_multiple_query_with_encoding_2) { + network::uri_builder builder; + builder + .scheme("http") + .host("example.com") + .append_query_key_value_pair("q1", "foo bar") + .append_query_key_value_pair("q2", "biz baz") + ; + ASSERT_EQ("http://example.com?q1=foo%20bar&q2=biz%20baz", builder.uri().string()); +} From ad5e013150b809d78d9f7eff4e5514e1641239f7 Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Sat, 14 May 2016 07:39:09 +0200 Subject: [PATCH 3/3] Cleaned up CMakeLists.txt and removed warnings --- .travis.yml | 2 +- CMakeLists.txt | 62 +++++++++++++++++++++---------- include/network/string_view.hpp | 1 + src/CMakeLists.txt | 2 +- src/detail/uri_advance_parts.cpp | 2 +- src/detail/uri_percent_encode.hpp | 5 --- src/uri.cpp | 6 ++- src/uri_builder.cpp | 4 +- test/optional_test.cpp | 2 +- test/uri_builder_test.cpp | 22 ----------- 10 files changed, 54 insertions(+), 54 deletions(-) diff --git a/.travis.yml b/.travis.yml index 369edf5a..2734870d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,7 +31,7 @@ script: - mkdir _builds - cd _builds # Note: clang not support libc++ - - cmake -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} -DCPP-NETLIB_DISABLE_LIBCXX=YES .. + - cmake -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} -DUri_DISABLE_LIBCXX=YES -DUri_BUILD_TESTS=ON -DUri_BUILD_DOCS=OFF .. - make -j 8 - make test diff --git a/CMakeLists.txt b/CMakeLists.txt index 598a980d..f4230b28 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,11 @@ cmake_minimum_required(VERSION 2.8) project(Uri) +option(Uri_BUILD_TESTS "Build the URI tests." ON) +option(Uri_BUILD_DOCS "Build the URI documentation." ON) +option(Uri_FULL_WARNINGS "Build the library with all warnings turned on." ON) +option(Uri_WARNINGS_AS_ERRORS "Treat warnings as errors." ON) + find_package(Threads REQUIRED) set(CMAKE_VERBOSE_MAKEFILE true) @@ -20,51 +25,68 @@ if (${CMAKE_CXX_COMPILER_ID} MATCHES GNU) else() message(FATAL_ERROR "No C++ 11 support (Compiler does not define -std=c++11).") endif() + + if (Uri_FULL_WARNINGS) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") + endif() + + if (Uri_WARNINGS_AS_ERRORS) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") + endif() + message("C++ Flags: ${CMAKE_CXX_FLAGS} link flags: ${CMAKE_CXX_LINK_FLAGS}") elseif(${CMAKE_CXX_COMPILER_ID} MATCHES Clang) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -ftemplate-depth=1024") - if (NOT CPP-NETLIB_DISABLE_LIBCXX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + + if (NOT Uri_DISABLE_LIBCXX) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") endif() + + if (Uri_FULL_WARNINGS) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") + endif() + + if (Uri_WARNINGS_AS_ERRORS) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") + endif() + message("C++ Flags: ${CMAKE_CXX_FLAGS} link flags: ${CMAKE_CXX_LINK_FLAGS}") endif() if (MSVC) - add_definitions(-D_SCL_SECURE_NO_WARNINGS -D_VARIADIC_MAX=10) -endif(MSVC) -if (WIN32) - add_definitions(-D_WIN32_WINNT=0x0501) -endif(WIN32) - -foreach(flag_var - CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE - CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) - if(${flag_var} MATCHES "/MD") + message(FATAL_ERROR "The current implementation uses features that aren't fully implemented on MSVC.") + + foreach(flag_var + CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE + CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) + if(${flag_var} MATCHES "/MD") string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") - endif(${flag_var} MATCHES "/MD") -endforeach(flag_var) + endif(${flag_var} MATCHES "/MD") + endforeach(flag_var) +endif(MSVC) include_directories(${Uri_SOURCE_DIR}/src ${Uri_SOURCE_DIR}/include) add_subdirectory(src) # Testing -if (CMAKE_PROJECT_NAME STREQUAL "Uri" OR CPP-NETLIB_BUILD_TESTS) +if (Uri_BUILD_TESTS) + message(STATUS "Configuring tests") enable_testing() add_subdirectory(deps/googletest) add_subdirectory(test) endif() # Documentation -find_package(Doxygen) -if (DOXYGEN_FOUND) - if (NOT DEFINED CPP-NETLIB_GENERATE_DOCS) +if (Uri_BUILD_DOCS) + message("Configuring documentation") + find_package(Doxygen) + if (DOXYGEN_FOUND) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY) add_custom_target(doc ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Generating API documentation with Doxygen" VERBATIM) - set(CPP-NETLIB_GENERATE_DOCS ON) endif() -endif(DOXYGEN_FOUND) +endif() diff --git a/include/network/string_view.hpp b/include/network/string_view.hpp index 972bca5b..eeca6210 100644 --- a/include/network/string_view.hpp +++ b/include/network/string_view.hpp @@ -152,6 +152,7 @@ class basic_string_view { size_type copy(charT* s, size_type n, size_type pos = 0) const { size_type rlen = std::min(n, size() - pos); std::copy_n(begin() + pos, rlen, s); + return rlen; } constexpr basic_string_view substr(size_type pos = 0, diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 607c1d45..769e4142 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -17,7 +17,7 @@ set(Uri_SRCS add_library(network-uri ${Uri_SRCS}) target_link_libraries(network-uri) if(${CMAKE_CXX_COMPILER_ID} MATCHES Clang) - if (NOT CPP-NETLIB_DISABLE_LIBCXX) + if (NOT Uri_DISABLE_LIBCXX) target_link_libraries(network-uri "c++") endif() endif() diff --git a/src/detail/uri_advance_parts.cpp b/src/detail/uri_advance_parts.cpp index 88966206..86b43180 100644 --- a/src/detail/uri_advance_parts.cpp +++ b/src/detail/uri_advance_parts.cpp @@ -26,7 +26,7 @@ uri_part copy_part(const std::string &uri, string_view::const_iterator &it) { void advance_parts(string_view &uri_view, uri_parts &parts, const uri_parts &existing_parts) { - auto first = std::begin(uri_view), last = std::end(uri_view); + auto first = std::begin(uri_view); auto it = first; if (auto scheme = existing_parts.scheme) { diff --git a/src/detail/uri_percent_encode.hpp b/src/detail/uri_percent_encode.hpp index 2293215b..ab5134db 100644 --- a/src/detail/uri_percent_encode.hpp +++ b/src/detail/uri_percent_encode.hpp @@ -59,11 +59,6 @@ Iter decode_encoded_unreserved_chars(Iter first, Iter last) { while (it != last) { if (*it == '%') { const auto sfirst = it; - const auto slast = [&]() { - auto slast = it; - std::advance(slast, 3); - return slast; - }(); const auto opt_char = percent_encode(sfirst); if (opt_char && is_unreserved(*opt_char)) { *it2 = *opt_char; diff --git a/src/uri.cpp b/src/uri.cpp index 2b7c5b7d..238b1b92 100644 --- a/src/uri.cpp +++ b/src/uri.cpp @@ -57,6 +57,9 @@ inline optional make_arg(optional view) { } return nullopt; } + +template +inline void ignore(T) {} } // namespace void uri::initialize(optional scheme, @@ -374,6 +377,7 @@ uri uri::normalize(uri_comparison_level level) const { // need to parse the parts again as the underlying string has changed const_iterator it = std::begin(normalized_view), last = std::end(normalized_view); bool is_valid = detail::parse(it, last, parts); + ignore(is_valid); assert(is_valid); if (parts.hier_part.path) { @@ -448,7 +452,7 @@ uri uri::make_relative(const uri &other) const { result.initialize(optional(), optional(), optional(), optional(), other_path, query, fragment); - return std::move(result); + return result; } uri uri::resolve(const uri &base) const { diff --git a/src/uri_builder.cpp b/src/uri_builder.cpp index e10038d3..3ae64437 100644 --- a/src/uri_builder.cpp +++ b/src/uri_builder.cpp @@ -64,8 +64,8 @@ uri_builder &uri_builder::clear_user_info() { void uri_builder::set_host(string_type host) { host_ = string_type(); - auto end = network::uri::encode_host(std::begin(host), std::end(host), - std::back_inserter(*host_)); + network::uri::encode_host(std::begin(host), std::end(host), + std::back_inserter(*host_)); detail::transform(*host_, std::begin(*host_), [](char ch) { return std::tolower(ch, std::locale()); }); } diff --git a/test/optional_test.cpp b/test/optional_test.cpp index d1b858ea..d6dc9c4a 100644 --- a/test/optional_test.cpp +++ b/test/optional_test.cpp @@ -42,7 +42,7 @@ TEST(optional_test, value_constructor_string) { TEST(optional_test, rvalue_ref_constructor) { int value = 42; - network::optional opt{std::move(42)}; + network::optional opt{std::move(value)}; ASSERT_TRUE(opt); ASSERT_EQ(*opt, 42); } diff --git a/test/uri_builder_test.cpp b/test/uri_builder_test.cpp index 3525ad61..9deecb9f 100644 --- a/test/uri_builder_test.cpp +++ b/test/uri_builder_test.cpp @@ -758,25 +758,3 @@ TEST(builder_test, non_const_non_array_string_literals_should_work) { ; ASSERT_EQ("http://example.com/foo", builder.uri()); } - -TEST(builder_test, set_multiple_query_with_encoding) { - network::uri_builder builder; - builder - .scheme("http") - .host("example.com") - .append_query("q1=foo bar") - .append_query("q2=biz baz") - ; - ASSERT_EQ("http://example.com?q1=foo%20bar&q2=biz%20baz", builder.uri().string()); -} - -TEST(builder_test, set_multiple_query_with_encoding_2) { - network::uri_builder builder; - builder - .scheme("http") - .host("example.com") - .append_query_key_value_pair("q1", "foo bar") - .append_query_key_value_pair("q2", "biz baz") - ; - ASSERT_EQ("http://example.com?q1=foo%20bar&q2=biz%20baz", builder.uri().string()); -}