LCOV - code coverage report
Current view: top level - tests - catch_uri.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 128 128
Test Date: 2026-11-09 21:32:01 Functions: 100.0 % 2 2
Legend: Lines: hit not hit

            Line data    Source code
       1              : // Copyright (c) 2011-2026  Made to Order Software Corp.  All Rights Reserved
       2              : //
       3              : // https://snapwebsites.org/project/edhttp
       4              : // contact@m2osw.com
       5              : //
       6              : // This program is free software: you can redistribute it and/or modify
       7              : // it under the terms of the GNU General Public License as published by
       8              : // the Free Software Foundation, either version 3 of the License, or
       9              : // (at your option) any later version.
      10              : //
      11              : // This program is distributed in the hope that it will be useful,
      12              : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13              : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14              : // GNU General Public License for more details.
      15              : //
      16              : // You should have received a copy of the GNU General Public License
      17              : // along with this program.  If not, see <https://www.gnu.org/licenses/>.
      18              : 
      19              : /** \file
      20              :  * \brief Verify the uri class.
      21              :  *
      22              :  * This file implements tests to verify that the uri class functions.
      23              :  */
      24              : 
      25              : // edhttp
      26              : //
      27              : #include    <edhttp/uri.h>
      28              : 
      29              : #include    <edhttp/exception.h>
      30              : 
      31              : 
      32              : // self
      33              : //
      34              : #include    "catch_main.h"
      35              : 
      36              : 
      37              : // snapdev
      38              : //
      39              : #include    <snapdev/tokenize_string.h>
      40              : 
      41              : 
      42              : // snaplogger
      43              : //
      44              : #include    <snaplogger/message.h>
      45              : 
      46              : 
      47              : // C
      48              : //
      49              : #include    <string.h>
      50              : 
      51              : 
      52              : 
      53            7 : CATCH_TEST_CASE("uri", "[domain]")
      54              : {
      55            7 :     CATCH_START_SECTION("uri: verify already canonicalized URI")
      56              :     {
      57            3 :         edhttp::uri uri("http://snap.website/");
      58              : 
      59            1 :         CATCH_REQUIRE(uri.domain() == "snap");
      60            1 :         CATCH_REQUIRE(uri.top_level_domain() == ".website");
      61            1 :     }
      62            8 :     CATCH_END_SECTION()
      63              : 
      64            7 :     CATCH_START_SECTION("uri: verify URI without '/' after domain name")
      65              :     {
      66            3 :         edhttp::uri uri("http://snap.website");
      67              : 
      68            1 :         CATCH_REQUIRE(uri.domain() == "snap");
      69            1 :         CATCH_REQUIRE(uri.top_level_domain() == ".website");
      70            1 :         CATCH_REQUIRE(uri.get_original_uri() == "http://snap.website");
      71            1 :         CATCH_REQUIRE(uri.get_uri() == "http://snap.website/");
      72            1 :     }
      73            8 :     CATCH_END_SECTION()
      74              : 
      75            7 :     CATCH_START_SECTION("uri: verify URI with two slashes")
      76              :     {
      77            3 :         edhttp::uri uri("http://snap.website//");
      78              : 
      79            1 :         CATCH_REQUIRE(uri.domain() == "snap");
      80            1 :         CATCH_REQUIRE(uri.top_level_domain() == ".website");
      81            1 :         CATCH_REQUIRE(uri.get_original_uri() == "http://snap.website//");
      82            1 :         CATCH_REQUIRE(uri.get_uri() == "http://snap.website/");
      83            1 :     }
      84            8 :     CATCH_END_SECTION()
      85              : 
      86            7 :     CATCH_START_SECTION("uri: verify URI with multiple slashes and a path")
      87              :     {
      88            3 :         edhttp::uri uri("http://snap.website///and/a/path");
      89              : 
      90            1 :         CATCH_REQUIRE(uri.domain() == "snap");
      91            1 :         CATCH_REQUIRE(uri.top_level_domain() == ".website");
      92            1 :         CATCH_REQUIRE(uri.path() == "and/a/path");
      93            1 :         CATCH_REQUIRE(uri.get_original_uri() == "http://snap.website///and/a/path");
      94            1 :         CATCH_REQUIRE(uri.get_uri() == "http://snap.website/and/a/path");
      95            1 :     }
      96            8 :     CATCH_END_SECTION()
      97              : 
      98            7 :     CATCH_START_SECTION("uri: verify credentials")
      99              :     {
     100            1 :         char const * ptr = nullptr;
     101              : 
     102              :         {
     103            3 :             edhttp::uri uri("http://explicit:credentials@snapwebsites.org:8888/and-port");
     104              : 
     105            1 :             CATCH_REQUIRE(uri.domain() == "snapwebsites");
     106            1 :             CATCH_REQUIRE(uri.top_level_domain() == ".org");
     107            1 :             CATCH_REQUIRE(uri.path() == "and-port");
     108            1 :             CATCH_REQUIRE(uri.get_username() == "explicit");
     109            1 :             CATCH_REQUIRE(uri.get_password() == "credentials");
     110              : 
     111              :             // check the string buffer is still saying "credentials
     112              :             //
     113            1 :             std::string const & p(uri.get_password());
     114            1 :             ptr = reinterpret_cast<char const *>(p.data());
     115            1 :             CATCH_REQUIRE(strncmp(ptr, "credentials", 11) == 0);
     116            1 :         }
     117              : 
     118              :         // after destruction, the buffer should not have the password anymore
     119              :         //
     120              :         // avoid that test when the sanitizer is active, it will detect that
     121              :         // we're accessing memory that was deallocated
     122              :         //
     123              : #ifndef __SANITIZE_ADDRESS__
     124              :         CATCH_REQUIRE(strncmp(ptr, "credentials", 11) != 0);
     125              : #endif
     126              :     }
     127            8 :     CATCH_END_SECTION()
     128              : 
     129            7 :     CATCH_START_SECTION("uri: use set_uri() to test valid URIs")
     130              :     {
     131              :         struct uri_test
     132              :         {
     133              :             char const *    f_original_uri = nullptr;           // set_uri() with original
     134              :             char const *    f_uri = nullptr;                    // canonicalized
     135              :             char const *    f_redacted_uri = nullptr;           // canonicalized & password redacted
     136              :             char const *    f_hash_bang_uri = nullptr;          // canonicalized & keep hash bang if defined
     137              :             char const *    f_website_uri = nullptr;            // scheme + full domain
     138              :             char const *    f_website_uri_with_port = nullptr;  // scheme + full domain + port
     139              :             char const *    f_domain = nullptr;                 // domain name only (no sub-domain or TLD)
     140              :             char const *    f_full_domain = nullptr;            // full domain
     141              :             char const *    f_top_level_domain = nullptr;       // the TLD of the domain
     142              :             char const *    f_sub_domains = nullptr;            // complete list of sub-domains
     143              :             char const *    f_username = nullptr;               // the user name
     144              :             char const *    f_password = nullptr;               // the password
     145              :             char const *    f_scheme = nullptr;                 // scheme name
     146              :             char const *    f_path = nullptr;                   // complete path
     147              :             int             f_path_count = 0;                   // number of segments in the complete path
     148              :             int             f_port = 0;                         // the expected port
     149              :             bool            f_is_unix = false;                  // whether the input URI is a Unix path
     150              :             char const *    f_query_string = nullptr;           // the query string
     151              :             char const *    f_anchor = nullptr;                 // the string after the '#"
     152              :             char const *    f_hash_bang_path = nullptr;         // path defined after '#!'
     153              :         };
     154              : 
     155            1 :         uri_test uris[] =
     156              :         {
     157              :             {
     158              :                 .f_original_uri          = "https://me:p1@test.this.domain.net///with///a///path?var=value&other_var=more%20data#hello",
     159              :                 .f_uri                   = "https://me:p1@test.this.domain.net/with/a/path?other_var=more%20data&var=value#hello",
     160              :                 .f_redacted_uri          = "https://me:%2A%2A%2A@test.this.domain.net/with/a/path?other_var=more%20data&var=value#hello",
     161              :                 .f_hash_bang_uri         = nullptr,
     162              :                 .f_website_uri           = "https://test.this.domain.net/",
     163              :                 .f_website_uri_with_port = "https://test.this.domain.net/",
     164              :                 .f_domain                = "domain",
     165              :                 .f_full_domain           = "test.this.domain.net",
     166              :                 .f_top_level_domain      = ".net",
     167              :                 .f_sub_domains           = "test.this",
     168              :                 .f_username              = "me",
     169              :                 .f_password              = "p1",
     170              :                 .f_scheme                = "https",
     171              :                 .f_path                  = "with/a/path",
     172              :                 .f_path_count            = 3,
     173              :                 .f_port                  = 443,
     174              :                 .f_is_unix               = false,
     175              :                 .f_query_string          = "other_var=more%20data&var=value",
     176              :                 .f_anchor                = "hello",
     177              :                 .f_hash_bang_path        = "",
     178              :             },
     179              :             {
     180              :                 .f_original_uri          = "http://you:p2%5D@sub.test.this.domain.cloud///with///a///path?var=value&other_var=more%20data#!/extra/path",
     181              :                 .f_uri                   = "http://you:p2%5D@sub.test.this.domain.cloud/with/a/path?other_var=more%20data&var=value",
     182              :                 .f_redacted_uri          = "http://you:%2A%2A%2A@sub.test.this.domain.cloud/with/a/path?other_var=more%20data&var=value",
     183              :                 .f_hash_bang_uri         = "http://you:p2%5D@sub.test.this.domain.cloud/with/a/path?other_var=more%20data&var=value#!/extra/path",
     184              :                 .f_website_uri           = "http://sub.test.this.domain.cloud/",
     185              :                 .f_website_uri_with_port = "http://sub.test.this.domain.cloud/",
     186              :                 .f_domain                = "domain",
     187              :                 .f_full_domain           = "sub.test.this.domain.cloud",
     188              :                 .f_top_level_domain      = ".cloud",
     189              :                 .f_sub_domains           = "sub.test.this",
     190              :                 .f_username              = "you",
     191              :                 .f_password              = "p2]",
     192              :                 .f_scheme                = "http",
     193              :                 .f_path                  = "with/a/path",
     194              :                 .f_path_count            = 3,
     195              :                 .f_port                  = 80,
     196              :                 .f_is_unix               = false,
     197              :                 .f_query_string          = "other_var=more%20data&var=value",
     198              :                 .f_anchor                = "",
     199              :                 .f_hash_bang_path        = "extra/path",
     200              :             },
     201              :             {
     202              :                 .f_original_uri          = "ftp://you:p2%5B@sub.test.this.domain.cloud///with///a///path?var=value&other_var=more%20data#hello",
     203              :                 .f_uri                   = "ftp://you:p2%5B@sub.test.this.domain.cloud/with/a/path?other_var=more%20data&var=value#hello",
     204              :                 .f_redacted_uri          = "ftp://you:%2A%2A%2A@sub.test.this.domain.cloud/with/a/path?other_var=more%20data&var=value#hello",
     205              :                 .f_hash_bang_uri         = nullptr,
     206              :                 .f_website_uri           = "ftp://sub.test.this.domain.cloud/",
     207              :                 .f_website_uri_with_port = "ftp://sub.test.this.domain.cloud/",
     208              :                 .f_domain                = "domain",
     209              :                 .f_full_domain           = "sub.test.this.domain.cloud",
     210              :                 .f_top_level_domain      = ".cloud",
     211              :                 .f_sub_domains           = "sub.test.this",
     212              :                 .f_username              = "you",
     213              :                 .f_password              = "p2[",
     214              :                 .f_scheme                = "ftp",
     215              :                 .f_path                  = "with/a/path",
     216              :                 .f_path_count            = 3,
     217              :                 .f_port                  = 21,
     218              :                 .f_is_unix               = false,
     219              :                 .f_query_string          = "other_var=more%20data&var=value",
     220              :                 .f_anchor                = "hello",
     221              :                 .f_hash_bang_path        = "",
     222              :             },
     223              :             {
     224              :                 .f_original_uri          = "ssh://agent:secret@console.example.website///packages?PATH=/usr/bin",
     225              :                 .f_uri                   = "ssh://agent:secret@console.example.website/packages?PATH=%2Fusr%2Fbin",
     226              :                 .f_redacted_uri          = "ssh://agent:%2A%2A%2A@console.example.website/packages?PATH=%2Fusr%2Fbin",
     227              :                 .f_hash_bang_uri         = nullptr,
     228              :                 .f_website_uri           = "ssh://console.example.website/",
     229              :                 .f_website_uri_with_port = "ssh://console.example.website/",
     230              :                 .f_domain                = "example",
     231              :                 .f_full_domain           = "console.example.website",
     232              :                 .f_top_level_domain      = ".website",
     233              :                 .f_sub_domains           = "console",
     234              :                 .f_username              = "agent",
     235              :                 .f_password              = "secret",
     236              :                 .f_scheme                = "ssh",
     237              :                 .f_path                  = "packages",
     238              :                 .f_path_count            = 1,
     239              :                 .f_port                  = 22,
     240              :                 .f_is_unix               = false,
     241              :                 .f_query_string          = "PATH=/usr/bin",
     242              :                 .f_anchor                = "",
     243              :                 .f_hash_bang_path        = "",
     244              :             },
     245              :             {
     246              :                 .f_original_uri          = "telnet://user:password1@shell.example.org///packages?PATH=/usr/bin%3A/usr/sbin&=no-name",
     247              :                 .f_uri                   = "telnet://user:password1@shell.example.org/packages?%2A=no-name&PATH=%2Fusr%2Fbin%3A%2Fusr%2Fsbin",
     248              :                 .f_redacted_uri          = "telnet://user:%2A%2A%2A@shell.example.org/packages?%2A=no-name&PATH=%2Fusr%2Fbin%3A%2Fusr%2Fsbin",
     249              :                 .f_hash_bang_uri         = nullptr,
     250              :                 .f_website_uri           = "telnet://shell.example.org/",
     251              :                 .f_website_uri_with_port = "telnet://shell.example.org/",
     252              :                 .f_domain                = "example",
     253              :                 .f_full_domain           = "shell.example.org",
     254              :                 .f_top_level_domain      = ".org",
     255              :                 .f_sub_domains           = "shell",
     256              :                 .f_username              = "user",
     257              :                 .f_password              = "password1",
     258              :                 .f_scheme                = "telnet",
     259              :                 .f_path                  = "packages",
     260              :                 .f_path_count            = 1,
     261              :                 .f_port                  = 23,
     262              :                 .f_is_unix               = false,
     263              :                 .f_query_string          = "%2A=no-name&PATH=/usr/bin:/usr/sbin",
     264              :                 .f_anchor                = "",
     265              :                 .f_hash_bang_path        = "",
     266              :             },
     267              :             {
     268              :                 .f_original_uri          = "smtp://user:password1@mail.abc123.info///var/mail-boxes/user?PATH=/usr/bin%3A/usr/sbin#latest",
     269              :                 .f_uri                   = "smtp://user:password1@mail.abc123.info/var/mail-boxes/user?PATH=%2Fusr%2Fbin%3A%2Fusr%2Fsbin#latest",
     270              :                 .f_redacted_uri          = "smtp://user:%2A%2A%2A@mail.abc123.info/var/mail-boxes/user?PATH=%2Fusr%2Fbin%3A%2Fusr%2Fsbin#latest",
     271              :                 .f_hash_bang_uri         = nullptr,
     272              :                 .f_website_uri           = "smtp://mail.abc123.info/",
     273              :                 .f_website_uri_with_port = "smtp://mail.abc123.info/",
     274              :                 .f_domain                = "abc123",
     275              :                 .f_full_domain           = "mail.abc123.info",
     276              :                 .f_top_level_domain      = ".info",
     277              :                 .f_sub_domains           = "mail",
     278              :                 .f_username              = "user",
     279              :                 .f_password              = "password1",
     280              :                 .f_scheme                = "smtp",
     281              :                 .f_path                  = "var/mail-boxes/user",
     282              :                 .f_path_count            = 3,
     283              :                 .f_port                  = 25,
     284              :                 .f_is_unix               = false,
     285              :                 .f_query_string          = "PATH=/usr/bin:/usr/sbin",
     286              :                 .f_anchor                = "latest",
     287              :                 .f_hash_bang_path        = "",
     288              :             },
     289              :             {
     290              :                 .f_original_uri          = "gopher://gofer:yes%3Ano@gopher.wall.alexis.museum///gopher",
     291              :                 .f_uri                   = "gopher://gofer:yes%3Ano@gopher.wall.alexis.museum/gopher",
     292              :                 .f_redacted_uri          = "gopher://gofer:%2A%2A%2A@gopher.wall.alexis.museum/gopher",
     293              :                 .f_hash_bang_uri         = nullptr,
     294              :                 .f_website_uri           = "gopher://gopher.wall.alexis.museum/",
     295              :                 .f_website_uri_with_port = "gopher://gopher.wall.alexis.museum/",
     296              :                 .f_domain                = "alexis",
     297              :                 .f_full_domain           = "gopher.wall.alexis.museum",
     298              :                 .f_top_level_domain      = ".museum",
     299              :                 .f_sub_domains           = "gopher.wall",
     300              :                 .f_username              = "gofer",
     301              :                 .f_password              = "yes:no",
     302              :                 .f_scheme                = "gopher",
     303              :                 .f_path                  = "gopher",
     304              :                 .f_path_count            = 1,
     305              :                 .f_port                  = 70,
     306              :                 .f_is_unix               = false,
     307              :                 .f_query_string          = "",
     308              :                 .f_anchor                = "",
     309              :                 .f_hash_bang_path        = "",
     310              :             },
     311              :             {
     312              :                 .f_original_uri          = "time://realtime.atomic.cl/utc?leap-seconds=separate",
     313              :                 .f_uri                   = "time://realtime.atomic.cl/utc?leap-seconds=separate",
     314              :                 .f_redacted_uri          = "time://realtime.atomic.cl/utc?leap-seconds=separate",
     315              :                 .f_hash_bang_uri         = nullptr,
     316              :                 .f_website_uri           = "time://realtime.atomic.cl/",
     317              :                 .f_website_uri_with_port = "time://realtime.atomic.cl/",
     318              :                 .f_domain                = "atomic",
     319              :                 .f_full_domain           = "realtime.atomic.cl",
     320              :                 .f_top_level_domain      = ".cl",
     321              :                 .f_sub_domains           = "realtime",
     322              :                 .f_username              = "",
     323              :                 .f_password              = "",
     324              :                 .f_scheme                = "time",
     325              :                 .f_path                  = "utc",
     326              :                 .f_path_count            = 1,
     327              :                 .f_port                  = 37,
     328              :                 .f_is_unix               = false,
     329              :                 .f_query_string          = "leap-second=separate",
     330              :                 .f_anchor                = "",
     331              :                 .f_hash_bang_path        = "",
     332              :             },
     333              :             {
     334              :                 .f_original_uri          = "snapwebsites://@parlement.co.uk/////folder/electric/bill?line%5B3%5D=129.07#quantity",
     335              :                 .f_uri                   = "snapwebsites://parlement.co.uk:80/folder/electric/bill?line%5B3%5D=129.07#quantity",
     336              :                 .f_redacted_uri          = "snapwebsites://parlement.co.uk:80/folder/electric/bill?line%5B3%5D=129.07#quantity",
     337              :                 .f_hash_bang_uri         = nullptr,
     338              :                 .f_website_uri           = "snapwebsites://parlement.co.uk/",
     339              :                 .f_website_uri_with_port = "snapwebsites://parlement.co.uk:80/",
     340              :                 .f_domain                = "parlement",
     341              :                 .f_full_domain           = "parlement.co.uk",
     342              :                 .f_top_level_domain      = ".co.uk",
     343              :                 .f_sub_domains           = "",
     344              :                 .f_username              = "",
     345              :                 .f_password              = "",
     346              :                 .f_scheme                = "snapwebsites",
     347              :                 .f_path                  = "folder/electric/bill",
     348              :                 .f_path_count            = 3,
     349              :                 .f_port                  = 80,
     350              :                 .f_is_unix               = false,
     351              :                 .f_query_string          = "line[3]=129.07",
     352              :                 .f_anchor                = "quantity",
     353              :                 .f_hash_bang_path        = "",
     354              :             },
     355              :         };
     356              : 
     357              :     // query string handling
     358              :     //void                        set_query_option(std::string const & name, std::string const & value);
     359              :     //void                        unset_query_option(std::string const & name);
     360              :     //void                        set_query_string(std::string const & uri_query_string);
     361              :     //std::string                 query_string() const;
     362              :     //bool                        has_query_option(std::string const & name) const;
     363              :     //void                        clear_query_options();
     364              :     //std::string                 query_option(std::string const & name) const;
     365              :     //int                         query_option_count() const;
     366              :     //std::string                 query_option(int part, std::string & name) const;
     367              :     //uri_options_t const &       query_string_list() const;
     368              : 
     369            1 :         int part(0);
     370           10 :         for(auto t : uris)
     371              :         {
     372           27 :             edhttp::uri uri(t.f_original_uri);
     373              : 
     374              :             // sub-domains
     375              :             //
     376            9 :             std::list<std::string> sub_domains;
     377           45 :             snapdev::tokenize_string(sub_domains, t.f_sub_domains, {"."}, true);
     378              : 
     379              :             // path segments
     380              :             //
     381            9 :             std::list<std::string> segments;
     382           45 :             snapdev::tokenize_string(segments, t.f_path, {"/"}, true);
     383              : 
     384              :             // verify each value for each original
     385              :             //
     386            9 :             CATCH_REQUIRE(uri.get_original_uri() == t.f_original_uri);
     387            9 :             CATCH_REQUIRE(uri.get_uri() == t.f_uri);
     388           27 :             CATCH_REQUIRE(uri.get_uri(false, "***") == t.f_redacted_uri);
     389            9 :             if(t.f_hash_bang_uri != nullptr)
     390              :             {
     391            1 :                 CATCH_REQUIRE(uri.get_uri(true) == t.f_hash_bang_uri);
     392              :             }
     393            9 :             CATCH_REQUIRE(uri.get_website_uri() == t.f_website_uri);
     394            9 :             CATCH_REQUIRE(uri.get_website_uri(true) == t.f_website_uri_with_port);
     395            9 :             CATCH_REQUIRE(uri.domain() == t.f_domain);
     396            9 :             CATCH_REQUIRE(uri.sub_domains() == t.f_sub_domains);
     397            9 :             CATCH_REQUIRE(uri.sub_domain_count() == static_cast<int>(sub_domains.size()));
     398            9 :             CATCH_REQUIRE(uri.full_domain() == t.f_full_domain);
     399            9 :             CATCH_REQUIRE(uri.top_level_domain() == t.f_top_level_domain);
     400            9 :             CATCH_REQUIRE(uri.get_username() == t.f_username);
     401            9 :             CATCH_REQUIRE(uri.get_password() == t.f_password);
     402            9 :             CATCH_REQUIRE(uri.scheme() == t.f_scheme);
     403            9 :             CATCH_REQUIRE(uri.path() == t.f_path);
     404            9 :             CATCH_REQUIRE(uri.path_count() == t.f_path_count);
     405            9 :             CATCH_REQUIRE(uri.get_port() == t.f_port);
     406            9 :             CATCH_REQUIRE(uri.is_unix() == t.f_is_unix);
     407            9 :             CATCH_REQUIRE(uri.get_str_port() == std::to_string(t.f_port));
     408            9 :             CATCH_REQUIRE(uri.anchor() == t.f_anchor);
     409            9 :             CATCH_REQUIRE(uri.hash_bang_path() == t.f_hash_bang_path);
     410              : 
     411            9 :             advgetopt::string_list_t const & sub_domain_list(uri.sub_domains_list());
     412            9 :             CATCH_REQUIRE(sub_domain_list.size() == sub_domains.size());
     413            9 :             auto sub_domain_it(sub_domain_list.begin());
     414            9 :             part = 0;
     415           23 :             for(auto const & s : sub_domains)
     416              :             {
     417           14 :                 CATCH_REQUIRE(uri.sub_domain(part) == s);
     418           14 :                 CATCH_REQUIRE(*sub_domain_it == s);
     419           42 :                 CATCH_REQUIRE(uri.get_part("sub-domain", part) == s);
     420           14 :                 ++sub_domain_it;
     421           14 :                 ++part;
     422              :             }
     423              : 
     424            9 :             advgetopt::string_list_t const & path_list(uri.path_list());
     425            9 :             CATCH_REQUIRE(path_list.size() == segments.size());
     426            9 :             auto path_it(path_list.begin());
     427            9 :             part = 0;
     428           28 :             for(auto const & s : segments)
     429              :             {
     430           19 :                 CATCH_REQUIRE(uri.path_segment(part) == s);
     431           19 :                 CATCH_REQUIRE(*path_it == s);
     432           57 :                 CATCH_REQUIRE(uri.get_part("path", part) == s);
     433           19 :                 ++path_it;
     434           19 :                 ++part;
     435              :             }
     436              : 
     437              :             // try again with the get_part() function
     438              :             //
     439           27 :             CATCH_REQUIRE(uri.get_part("anchor") == t.f_anchor);
     440           27 :             CATCH_REQUIRE(uri.get_part("domain") == t.f_domain);
     441           27 :             CATCH_REQUIRE(uri.get_part("full-domain") == t.f_full_domain);
     442           27 :             CATCH_REQUIRE(uri.get_part("is-unix") == (t.f_is_unix ? "unix" : "inet"));
     443           27 :             CATCH_REQUIRE(uri.get_part("original") == t.f_original_uri);
     444           27 :             CATCH_REQUIRE(uri.get_part("password") == t.f_password);
     445           27 :             CATCH_REQUIRE(uri.get_part("path-count") == std::to_string(t.f_path_count));
     446           27 :             CATCH_REQUIRE(uri.get_part("port") == std::to_string(t.f_port));
     447           27 :             CATCH_REQUIRE(uri.get_part("scheme") == t.f_scheme);
     448           27 :             CATCH_REQUIRE(uri.get_part("tld") == t.f_top_level_domain);
     449           27 :             CATCH_REQUIRE(uri.get_part("top-level-domain") == t.f_top_level_domain);
     450           27 :             CATCH_REQUIRE(uri.get_part("uri") == t.f_uri);
     451           27 :             CATCH_REQUIRE(uri.get_part("username") == t.f_username);
     452              : 
     453              :             // unknown parts are accepted and the function returns an empty string
     454              :             //
     455           27 :             CATCH_REQUIRE(uri.get_part("anything-else-is-empty") == std::string());
     456            9 :         }
     457              :     }
     458            8 :     CATCH_END_SECTION()
     459              : 
     460            7 :     CATCH_START_SECTION("uri: use set_uri() to test invalid URIs")
     461              :     {
     462              :         struct uri_test
     463              :         {
     464              :             char const *    f_uri = nullptr;                    // some invalid URI
     465              :             char const *    f_error_message = nullptr;          // the expected error message
     466              :         };
     467              : 
     468            1 :         uri_test uris[] =
     469              :         {
     470              :             {
     471              :                 .f_uri           = "https",
     472              :                 .f_error_message = "scheme not followed by \"://\".",
     473              :             },
     474              :             {
     475              :                 .f_uri           = "https://@m2osw.com:80:80/",
     476              :                 .f_error_message = "more than one ':' in the domain name segment (after the '@') [1].",
     477              :             },
     478              :             {
     479              :                 .f_uri           = "https:///this.domain.net///with///a///path?var=value&other_var=more%20data#hello",
     480              :                 .f_error_message = "a domain name is required.",
     481              :             },
     482              :             {
     483              :                 .f_uri           = "https://top:secret:password@m2osw.com:80:80/",
     484              :                 .f_error_message = "more than one ':' in the login info segment (before the '@').",
     485              :             },
     486              :             {
     487              :                 .f_uri           = "https://top:secret@password@m2osw.com:80:80/",
     488              :                 .f_error_message = "more than one '@' character found.",
     489              :             },
     490              :             {
     491              :                 .f_uri           = "https://my:password@m2osw.com:80:80/",
     492              :                 .f_error_message = "more than one ':' in the domain name segment (after the '@') [2].",
     493              :             },
     494              :             {
     495              :                 .f_uri           = "https://empty:port@m2osw.com:/",
     496              :                 .f_error_message = "port cannot be an empty string.",
     497              :             },
     498              :             {
     499              :                 .f_uri           = "https://empty:port@m2osw.com:http/",
     500              :                 .f_error_message = "port must be a valid decimal number ('http' unexpected).",
     501              :             },
     502              :             {
     503              :                 .f_uri           = "https://big:port@m2osw.com:65536/",
     504              :                 .f_error_message = "port must be between 0 and 65536.",
     505              :             },
     506              :             {
     507              :                 .f_uri           = "https://no:domain@:65535/no/domain",
     508              :                 .f_error_message = "a domain name is required.",
     509              :             },
     510              :             {
     511              :                 .f_uri           = "https://empty:@password.m2osw.com:1001/",
     512              :                 .f_error_message = "username and password must both be defined (or define neither).",
     513              :             },
     514              :             {
     515              :                 .f_uri           = "https://:empty@password.m2osw.com:1001/",
     516              :                 .f_error_message = "username and password must both be defined (or define neither).",
     517              :             },
     518              :             {
     519              :                 .f_uri           = "https://utc.m2osw.clock/",
     520              :                 .f_error_message = "could not verify domain name \"utc.m2osw.clock\".",
     521              :             },
     522              :             {
     523              :                 .f_uri           = "https://utc.m2osw.co/?a=1&a=3",
     524              :                 .f_error_message = "query string \"a\" found more than once.",
     525              :             },
     526              :             {
     527              :                 .f_uri           = "https://parent.m2osw.co/..",
     528              :                 .f_error_message = "found \"..\" at the beginning of your path.",
     529              :             },
     530              :             {
     531              :                 .f_uri           = "https://parent.m2osw.co/../none",
     532              :                 .f_error_message = "found \"..\" at the beginning of your path.",
     533              :             },
     534              :             {
     535              :                 .f_uri           = "https://parent.m2osw.co/./../sub-domain",
     536              :                 .f_error_message = "found \"..\" at the beginning of your path.",
     537              :             },
     538              :         };
     539              : 
     540           18 :         for(auto t : uris)
     541              :         {
     542           17 :             edhttp::uri uri;
     543              : 
     544           51 :             CATCH_REQUIRE_FALSE(uri.set_uri(t.f_uri));
     545           17 :             CATCH_REQUIRE(uri.get_last_error_message() == t.f_error_message);
     546           17 :             uri.clear_last_error_message();
     547           17 :             CATCH_REQUIRE(uri.get_last_error_message().empty());
     548           17 :         }
     549              :     }
     550            8 :     CATCH_END_SECTION()
     551            7 : }
     552              : 
     553              : 
     554            1 : CATCH_TEST_CASE("uri_error", "[domain][error]")
     555              : {
     556            1 :     CATCH_START_SECTION("uri_error: create uri with an invalid string")
     557              :     {
     558            8 :         CATCH_REQUIRE_THROWS_MATCHES(
     559              :                   edhttp::uri("bad_URI")
     560              :                 , edhttp::invalid_uri
     561              :                 , Catch::Matchers::ExceptionMessage(
     562              :                           "edhttp_exception: URI \"bad_URI\" is considered invalid."));
     563              :     }
     564            2 :     CATCH_END_SECTION()
     565            1 : }
     566              : 
     567              : 
     568              : // vim: ts=4 sw=4 et
        

Generated by: LCOV version 2.0-1

Snap C++ | List of projects | List of versions