diff --git a/exporters/elasticsearch/src/es_log_record_exporter.cc b/exporters/elasticsearch/src/es_log_record_exporter.cc index 3b3e8c4aeb..bfc1ad3d64 100644 --- a/exporters/elasticsearch/src/es_log_record_exporter.cc +++ b/exporters/elasticsearch/src/es_log_record_exporter.cc @@ -323,7 +323,7 @@ sdk::common::ExportResult ElasticsearchLogRecordExporter::Export( } // Create a connection to the ElasticSearch instance - auto session = http_client_->CreateSession(options_.host_ + std::to_string(options_.port_)); + auto session = http_client_->CreateSession(options_.host_ + ":" + std::to_string(options_.port_)); auto request = session->CreateRequest(); // Populate the request with headers and methods diff --git a/ext/include/opentelemetry/ext/http/common/url_parser.h b/ext/include/opentelemetry/ext/http/common/url_parser.h index 386d4fcd2f..75f53ce943 100644 --- a/ext/include/opentelemetry/ext/http/common/url_parser.h +++ b/ext/include/opentelemetry/ext/http/common/url_parser.h @@ -65,7 +65,7 @@ class UrlParser cpos = pos1 + 1; } } - pos = url_.find_first_of(":", cpos); + pos = FindPortPosition(url_, cpos); bool is_port = false; if (pos == std::string::npos) { @@ -130,6 +130,40 @@ class UrlParser query_ = std::string(url_.begin() + cpos, url_.begin() + url_.length()); } } + +private: + static std::string::size_type FindPortPosition(const std::string &url, + std::string::size_type offset) + { + // @see https://www.rfc-editor.org/rfc/rfc3986#page-18 + size_t sub_expression_counter = 0; + for (std::string::size_type i = offset; i < url.size(); ++i) + { + char c = url[i]; + if (0 == sub_expression_counter && c == ':') + { + return i; + } + + if (c == '[') + { + ++sub_expression_counter; + } + else if (c == ']') + { + if (sub_expression_counter > 0) + { + --sub_expression_counter; + } + } + else if (0 == sub_expression_counter && c == '/') + { + break; + } + } + + return std::string::npos; + } }; class UrlDecoder diff --git a/ext/test/http/url_parser_test.cc b/ext/test/http/url_parser_test.cc index 79a5e60a60..aceb43966a 100644 --- a/ext/test/http/url_parser_test.cc +++ b/ext/test/http/url_parser_test.cc @@ -123,7 +123,62 @@ TEST(UrlParserTests, BasicTests) {"path", "/path1@bbb/path2"}, {"query", "q1=a1&q2=a2"}, {"success", "true"}}}, - + {"http://1.2.3.4/path1/path2?q1=a1&q2=a2", + {{"host", "1.2.3.4"}, + {"port", "80"}, + {"scheme", "http"}, + {"path", "/path1/path2"}, + {"query", "q1=a1&q2=a2"}, + {"success", "true"}}}, + {"user:password@1.2.3.4:8080/path1/path2?q1=a1&q2=a2", + {{"host", "1.2.3.4"}, + {"port", "8080"}, + {"scheme", "http"}, + {"path", "/path1/path2"}, + {"query", "q1=a1&q2=a2"}, + {"success", "true"}}}, + {"https://user@1.2.3.4/path1/path2?q1=a1&q2=a2", + {{"host", "1.2.3.4"}, + {"port", "443"}, + {"scheme", "https"}, + {"path", "/path1/path2"}, + {"query", "q1=a1&q2=a2"}, + {"success", "true"}}}, + {"http://1.2.3.4/path1@bbb/path2?q1=a1&q2=a2", + {{"host", "1.2.3.4"}, + {"port", "80"}, + {"scheme", "http"}, + {"path", "/path1@bbb/path2"}, + {"query", "q1=a1&q2=a2"}, + {"success", "true"}}}, + {"http://[fe80::225:93da:bfde:b5f5]/path1/path2?q1=a1&q2=a2", + {{"host", "[fe80::225:93da:bfde:b5f5]"}, + {"port", "80"}, + {"scheme", "http"}, + {"path", "/path1/path2"}, + {"query", "q1=a1&q2=a2"}, + {"success", "true"}}}, + {"user:password@[fe80::225:93da:bfde:b5f5]:8080/path1/path2?q1=a1&q2=a2", + {{"host", "[fe80::225:93da:bfde:b5f5]"}, + {"port", "8080"}, + {"scheme", "http"}, + {"path", "/path1/path2"}, + {"query", "q1=a1&q2=a2"}, + {"success", "true"}}}, + {"https://user@[fe80::225:93da:bfde:b5f5]/path1/path2?q1=a1&q2=a2", + {{"host", "[fe80::225:93da:bfde:b5f5]"}, + {"port", "443"}, + {"scheme", "https"}, + {"path", "/path1/path2"}, + {"query", "q1=a1&q2=a2"}, + {"success", "true"}}}, + {"http://[fe80::225:93da:bfde:b5f5]/path1@bbb/path2?q1=a1&q2=a2", + {{"host", "[fe80::225:93da:bfde:b5f5]"}, + {"port", "80"}, + {"scheme", "http"}, + {"path", "/path1@bbb/path2"}, + {"query", "q1=a1&q2=a2"}, + {"success", "true"}}}, }; for (auto &url_map : urls_map) {