1 // Copyright (C) 2017-2018 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #include <config.h>
8 #include <http/url.h>
9 #include <gtest/gtest.h>
10 #include <string>
11 
12 using namespace isc::http;
13 
14 namespace {
15 
16 /// @brief Test fixture class for @c Url class.
17 class UrlTest : public ::testing::Test {
18 public:
19 
20     /// @brief Test valid URL.
21     ///
22     /// @param text_url URL is the text form.
23     /// @param expected_scheme Expected scheme.
24     /// @param expected_hostname Expected hostname.
25     /// @param expected_port Expected port.
26     /// @param expected_path Expected path.
testValidUrl(const std::string & text_url,const Url::Scheme & expected_scheme,const std::string & expected_hostname,const unsigned expected_port,const std::string & expected_path)27     void testValidUrl(const std::string& text_url,
28                       const Url::Scheme& expected_scheme,
29                       const std::string& expected_hostname,
30                       const unsigned expected_port,
31                       const std::string& expected_path) {
32         Url url(text_url);
33         ASSERT_TRUE(url.isValid()) << url.getErrorMessage();
34         EXPECT_EQ(expected_scheme, url.getScheme());
35         EXPECT_EQ(expected_hostname, url.getStrippedHostname());
36         EXPECT_EQ(expected_port, url.getPort());
37         EXPECT_EQ(expected_path, url.getPath());
38     }
39 
40     /// @brief Test invalid URL.
41     ///
42     /// @param text_url URL is the text form.
testInvalidUrl(const std::string & text_url)43     void testInvalidUrl(const std::string& text_url) {
44         Url url(text_url);
45         EXPECT_FALSE(url.isValid());
46     }
47 };
48 
49 // URL contains scheme and hostname.
TEST_F(UrlTest,schemeHostname)50 TEST_F(UrlTest, schemeHostname) {
51     testValidUrl("http://example.org", Url::HTTP, "example.org", 0, "");
52 }
53 
54 // URL contains scheme, hostname and slash.
TEST_F(UrlTest,schemeHostnameSlash)55 TEST_F(UrlTest, schemeHostnameSlash) {
56     testValidUrl("http://example.org/", Url::HTTP, "example.org", 0, "/");
57 }
58 
59 // URL contains scheme, IPv6 address and slash.
TEST_F(UrlTest,schemeIPv6AddressSlash)60 TEST_F(UrlTest, schemeIPv6AddressSlash) {
61     testValidUrl("http://[2001:db8:1::100]/", Url::HTTP, "2001:db8:1::100", 0, "/");
62 }
63 
64 // URL contains scheme, IPv4 address and slash.
TEST_F(UrlTest,schemeIPv4AddressSlash)65 TEST_F(UrlTest, schemeIPv4AddressSlash) {
66     testValidUrl("http://192.0.2.2/", Url::HTTP, "192.0.2.2", 0, "/");
67 }
68 
69 // URL contains scheme, hostname and path.
TEST_F(UrlTest,schemeHostnamePath)70 TEST_F(UrlTest, schemeHostnamePath) {
71     testValidUrl("http://example.org/some/path", Url::HTTP, "example.org", 0,
72                  "/some/path");
73 }
74 
75 // URL contains scheme, hostname and port.
TEST_F(UrlTest,schemeHostnamePort)76 TEST_F(UrlTest, schemeHostnamePort) {
77     testValidUrl("http://example.org:8080/", Url::HTTP, "example.org", 8080, "/");
78 }
79 
80 // URL contains scheme, hostname, port and slash.
TEST_F(UrlTest,schemeHostnamePortSlash)81 TEST_F(UrlTest, schemeHostnamePortSlash) {
82     testValidUrl("http://example.org:8080/", Url::HTTP, "example.org", 8080, "/");
83 }
84 
85 // URL contains scheme, IPv6 address and port.
TEST_F(UrlTest,schemeIPv6AddressPort)86 TEST_F(UrlTest, schemeIPv6AddressPort) {
87     testValidUrl("http://[2001:db8:1::1]:8080/", Url::HTTP, "2001:db8:1::1", 8080, "/");
88 }
89 
90 // URL contains scheme, hostname, port and path.
TEST_F(UrlTest,schemeHostnamePortPath)91 TEST_F(UrlTest, schemeHostnamePortPath) {
92     testValidUrl("http://example.org:8080/path/", Url::HTTP, "example.org", 8080,
93                  "/path/");
94 }
95 
96 // URL contains https scheme, hostname, port and path.
TEST_F(UrlTest,secureSchemeHostnamePortPath)97 TEST_F(UrlTest, secureSchemeHostnamePortPath) {
98     testValidUrl("https://example.org:8080/path/", Url::HTTPS, "example.org", 8080,
99                  "/path/");
100 }
101 
102 // Tests various invalid URLS.
TEST_F(UrlTest,invalidUrls)103 TEST_F(UrlTest, invalidUrls) {
104     testInvalidUrl("example.org");
105     testInvalidUrl("file://example.org");
106     testInvalidUrl("http//example.org");
107     testInvalidUrl("http:/example.org");
108     testInvalidUrl("http://");
109     testInvalidUrl("http://[]");
110     testInvalidUrl("http://[2001:db8:1::1");
111     testInvalidUrl("http://example.org:");
112     testInvalidUrl("http://example.org:abc");
113 }
114 
115 }
116