Created
November 28, 2023 10:52
-
-
Save eao197/00272a76b3a358a580af2627c2d7fd88 to your computer and use it in GitHub Desktop.
Пример парсинга адреса сервера вида "http://localhost:8088/" имеющимися в RESTinio средствами. С разбором на составляющие: (http|https), (host|ipv6|ipv4) и опциональный порт
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN | |
| #include <doctest/doctest.h> | |
| #include <restinio/helpers/http_field_parsers/host.hpp> | |
| namespace example | |
| { | |
| namespace ep = restinio::easy_parser; | |
| using restinio::http_field_parsers::host_details::ipv4_address_p; | |
| using restinio::http_field_parsers::host_details::ipv6_address_p; | |
| using restinio::http_field_parsers::host_details::reg_name_p; | |
| enum class protocol_t { http, https }; | |
| struct server_address_params_t | |
| { | |
| protocol_t m_protocol{ protocol_t::http }; | |
| std::string m_address{ "localhost" }; | |
| std::optional< std::uint16_t > m_port; | |
| }; | |
| [[nodiscard]] | |
| auto | |
| server_address_params_p() | |
| { | |
| return ep::produce< server_address_params_t >( | |
| ep::produce< protocol_t >( | |
| ep::alternatives( | |
| ep::exact_p( "https" ) | |
| >> ep::just( protocol_t::https ) >> ep::as_result(), | |
| ep::exact_p( "http" ) | |
| >> ep::just( protocol_t::http ) >> ep::as_result() | |
| ) | |
| ) >> &server_address_params_t::m_protocol, | |
| ep::exact( "://" ), | |
| ep::produce< std::string >( | |
| ep::alternatives( | |
| ep::sequence( | |
| ep::symbol( '[' ), | |
| ipv6_address_p() >> ep::as_result(), | |
| ep::symbol( ']' ) | |
| ), | |
| ipv4_address_p() >> ep::as_result(), | |
| reg_name_p() >> ep::as_result() | |
| ) | |
| ) >> &server_address_params_t::m_address, | |
| ep::produce< std::optional< std::uint16_t > >( | |
| ep::maybe( | |
| ep::symbol(':'), | |
| ep::non_negative_decimal_number_p< std::uint16_t >() >> ep::as_result() | |
| ) | |
| ) >> &server_address_params_t::m_port, | |
| ep::maybe( ep::symbol( '/' ) ) | |
| ); | |
| } | |
| [[nodiscard]] | |
| restinio::expected_t< server_address_params_t, ep::parse_error_t > | |
| try_parse( std::string_view what ) | |
| { | |
| return ep::try_parse( what, server_address_params_p() ); | |
| } | |
| } /* namespace example */ | |
| TEST_CASE( "hostname" ) | |
| { | |
| { | |
| const auto r = example::try_parse( "http://localhost" ); | |
| REQUIRE( true == r.has_value() ); | |
| const auto & srv = *r; | |
| REQUIRE( example::protocol_t::http == srv.m_protocol ); | |
| REQUIRE( "localhost" == srv.m_address ); | |
| REQUIRE( !srv.m_port ); | |
| } | |
| { | |
| const auto r = example::try_parse( "http://localhost/" ); | |
| REQUIRE( true == r.has_value() ); | |
| const auto & srv = *r; | |
| REQUIRE( example::protocol_t::http == srv.m_protocol ); | |
| REQUIRE( "localhost" == srv.m_address ); | |
| REQUIRE( !srv.m_port ); | |
| } | |
| { | |
| const auto r = example::try_parse( "http://localhost:8080" ); | |
| REQUIRE( true == r.has_value() ); | |
| const auto & srv = *r; | |
| REQUIRE( example::protocol_t::http == srv.m_protocol ); | |
| REQUIRE( "localhost" == srv.m_address ); | |
| REQUIRE( true == srv.m_port.has_value() ); | |
| REQUIRE( 8080 == srv.m_port.value() ); | |
| } | |
| { | |
| const auto r = example::try_parse( "http://localhost:8080/" ); | |
| REQUIRE( true == r.has_value() ); | |
| const auto & srv = *r; | |
| REQUIRE( example::protocol_t::http == srv.m_protocol ); | |
| REQUIRE( "localhost" == srv.m_address ); | |
| REQUIRE( true == srv.m_port.has_value() ); | |
| REQUIRE( 8080 == srv.m_port.value() ); | |
| } | |
| { | |
| const auto r = example::try_parse( "http://my.host-name.com:55777/" ); | |
| REQUIRE( true == r.has_value() ); | |
| const auto & srv = *r; | |
| REQUIRE( example::protocol_t::http == srv.m_protocol ); | |
| REQUIRE( "my.host-name.com" == srv.m_address ); | |
| REQUIRE( true == srv.m_port.has_value() ); | |
| REQUIRE( 55777 == srv.m_port.value() ); | |
| } | |
| { | |
| const auto r = example::try_parse( "https://my.host-name.com:55777/" ); | |
| REQUIRE( true == r.has_value() ); | |
| const auto & srv = *r; | |
| REQUIRE( example::protocol_t::https == srv.m_protocol ); | |
| REQUIRE( "my.host-name.com" == srv.m_address ); | |
| REQUIRE( true == srv.m_port.has_value() ); | |
| REQUIRE( 55777 == srv.m_port.value() ); | |
| } | |
| } | |
| TEST_CASE( "ipv6" ) | |
| { | |
| { | |
| const auto r = example::try_parse( "http://[::]" ); | |
| REQUIRE( true == r.has_value() ); | |
| const auto & srv = *r; | |
| REQUIRE( example::protocol_t::http == srv.m_protocol ); | |
| REQUIRE( "::" == srv.m_address ); | |
| REQUIRE( !srv.m_port ); | |
| } | |
| { | |
| const auto r = example::try_parse( "http://[::]/" ); | |
| REQUIRE( true == r.has_value() ); | |
| const auto & srv = *r; | |
| REQUIRE( example::protocol_t::http == srv.m_protocol ); | |
| REQUIRE( "::" == srv.m_address ); | |
| REQUIRE( !srv.m_port ); | |
| } | |
| { | |
| const auto r = example::try_parse( "http://[::1]/" ); | |
| REQUIRE( true == r.has_value() ); | |
| const auto & srv = *r; | |
| REQUIRE( example::protocol_t::http == srv.m_protocol ); | |
| REQUIRE( "::1" == srv.m_address ); | |
| REQUIRE( !srv.m_port ); | |
| } | |
| { | |
| const auto r = example::try_parse( "http://[::]:8080" ); | |
| REQUIRE( true == r.has_value() ); | |
| const auto & srv = *r; | |
| REQUIRE( example::protocol_t::http == srv.m_protocol ); | |
| REQUIRE( "::" == srv.m_address ); | |
| REQUIRE( true == srv.m_port.has_value() ); | |
| REQUIRE( 8080 == srv.m_port.value() ); | |
| } | |
| { | |
| const auto r = example::try_parse( "http://[::]:8080/" ); | |
| REQUIRE( true == r.has_value() ); | |
| const auto & srv = *r; | |
| REQUIRE( example::protocol_t::http == srv.m_protocol ); | |
| REQUIRE( "::" == srv.m_address ); | |
| REQUIRE( true == srv.m_port.has_value() ); | |
| REQUIRE( 8080 == srv.m_port.value() ); | |
| } | |
| { | |
| const auto r = example::try_parse( "http://[FF01::43]:55777/" ); | |
| REQUIRE( true == r.has_value() ); | |
| const auto & srv = *r; | |
| REQUIRE( example::protocol_t::http == srv.m_protocol ); | |
| REQUIRE( "FF01::43" == srv.m_address ); | |
| REQUIRE( true == srv.m_port.has_value() ); | |
| REQUIRE( 55777 == srv.m_port.value() ); | |
| } | |
| { | |
| const auto r = example::try_parse( "http://[::FFFF:129.144.52.38]:55777/" ); | |
| REQUIRE( true == r.has_value() ); | |
| const auto & srv = *r; | |
| REQUIRE( example::protocol_t::http == srv.m_protocol ); | |
| REQUIRE( "::FFFF:129.144.52.38" == srv.m_address ); | |
| REQUIRE( true == srv.m_port.has_value() ); | |
| REQUIRE( 55777 == srv.m_port.value() ); | |
| } | |
| } | |
| TEST_CASE( "ipv4" ) | |
| { | |
| { | |
| const auto r = example::try_parse( "http://127.0.0.1" ); | |
| REQUIRE( true == r.has_value() ); | |
| const auto & srv = *r; | |
| REQUIRE( example::protocol_t::http == srv.m_protocol ); | |
| REQUIRE( "127.0.0.1" == srv.m_address ); | |
| REQUIRE( !srv.m_port ); | |
| } | |
| { | |
| const auto r = example::try_parse( "http://127.0.0.1/" ); | |
| REQUIRE( true == r.has_value() ); | |
| const auto & srv = *r; | |
| REQUIRE( example::protocol_t::http == srv.m_protocol ); | |
| REQUIRE( "127.0.0.1" == srv.m_address ); | |
| REQUIRE( !srv.m_port ); | |
| } | |
| { | |
| const auto r = example::try_parse( "http://127.0.0.1:8080" ); | |
| REQUIRE( true == r.has_value() ); | |
| const auto & srv = *r; | |
| REQUIRE( example::protocol_t::http == srv.m_protocol ); | |
| REQUIRE( "127.0.0.1" == srv.m_address ); | |
| REQUIRE( true == srv.m_port.has_value() ); | |
| REQUIRE( 8080 == srv.m_port.value() ); | |
| } | |
| { | |
| const auto r = example::try_parse( "http://127.0.0.1:8080/" ); | |
| REQUIRE( true == r.has_value() ); | |
| const auto & srv = *r; | |
| REQUIRE( example::protocol_t::http == srv.m_protocol ); | |
| REQUIRE( "127.0.0.1" == srv.m_address ); | |
| REQUIRE( true == srv.m_port.has_value() ); | |
| REQUIRE( 8080 == srv.m_port.value() ); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment