Unverified Commit 94d06576 authored by Dennis Jenkins's avatar Dennis Jenkins Committed by GitHub

Merge pull request #498 from knowledge4igor/partially_fix_issue_420

Partially fix issue #420
parents 30f8b58e 4dbac64d
#pragma once #pragma once
#include <cstddef> #include <cstddef>
#include <cstdint>
// Allow compile-time overload // Allow compile-time overload
namespace Pistache namespace Pistache
...@@ -17,5 +18,7 @@ namespace Const ...@@ -17,5 +18,7 @@ namespace Const
// Defined from CMakeLists.txt in project root // Defined from CMakeLists.txt in project root
static constexpr size_t DefaultMaxPayload = 4096; static constexpr size_t DefaultMaxPayload = 4096;
static constexpr size_t ChunkSize = 1024; static constexpr size_t ChunkSize = 1024;
static constexpr uint16_t HTTP_STANDARD_PORT = 80;
} // namespace Const } // namespace Const
} // namespace Pistache } // namespace Pistache
\ No newline at end of file
...@@ -119,7 +119,6 @@ namespace Http { ...@@ -119,7 +119,6 @@ namespace Http {
CHARSET(Utf32-LE, "utf-32le") \ CHARSET(Utf32-LE, "utf-32le") \
CHARSET(Unicode-11, "unicode-1-1") CHARSET(Unicode-11, "unicode-1-1")
const uint16_t HTTP_STANDARD_PORT = 80;
enum class Method { enum class Method {
#define METHOD(m, _) m, #define METHOD(m, _) m,
......
...@@ -128,11 +128,13 @@ public: ...@@ -128,11 +128,13 @@ public:
explicit AddressParser(const std::string& data); explicit AddressParser(const std::string& data);
const std::string& rawHost() const; const std::string& rawHost() const;
const std::string& rawPort() const; const std::string& rawPort() const;
bool hasColon() const;
int family() const; int family() const;
private: private:
std::string host_; std::string host_;
std::string port_; std::string port_;
int family_; bool hasColon_ = false;
int family_ = 0;
}; };
class Address { class Address {
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <pistache/http_header.h> #include <pistache/http_header.h>
#include <pistache/common.h> #include <pistache/common.h>
#include <pistache/config.h>
#include <pistache/http.h> #include <pistache/http.h>
#include <pistache/stream.h> #include <pistache/stream.h>
...@@ -342,7 +343,7 @@ void Host::parse(const std::string& data) ...@@ -342,7 +343,7 @@ void Host::parse(const std::string& data)
const std::string& port = parser.rawPort(); const std::string& port = parser.rawPort();
if (port.empty()) if (port.empty())
{ {
port_ = HTTP_STANDARD_PORT; port_ = Const::HTTP_STANDARD_PORT;
} }
else else
{ {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <pistache/net.h> #include <pistache/net.h>
#include <pistache/common.h> #include <pistache/common.h>
#include <pistache/config.h>
#include <stdexcept> #include <stdexcept>
#include <limits> #include <limits>
...@@ -195,13 +196,23 @@ AddressParser::AddressParser(const std::string& data) ...@@ -195,13 +196,23 @@ AddressParser::AddressParser(const std::string& data)
end_pos != std::string::npos && end_pos != std::string::npos &&
start_pos < end_pos) start_pos < end_pos)
{ {
std::size_t colon_pos = data.find_first_of(':', end_pos);
if (colon_pos != std::string::npos)
{
hasColon_ = true;
}
host_ = data.substr(start_pos, end_pos + 1); host_ = data.substr(start_pos, end_pos + 1);
family_ = AF_INET6; family_ = AF_INET6;
++end_pos; ++end_pos;
} }
else else
{ {
end_pos = data.find(':'); std::size_t colon_pos = data.find(':');
if (colon_pos != std::string::npos)
{
hasColon_ = true;
}
end_pos = colon_pos;
host_ = data.substr(0, end_pos); host_ = data.substr(0, end_pos);
family_ = AF_INET; family_ = AF_INET;
} }
...@@ -224,6 +235,11 @@ const std::string& AddressParser::rawPort() const ...@@ -224,6 +235,11 @@ const std::string& AddressParser::rawPort() const
return port_; return port_;
} }
bool AddressParser::hasColon() const
{
return hasColon_;
}
int AddressParser::family() const int AddressParser::family() const
{ {
return family_; return family_;
...@@ -327,6 +343,19 @@ void Address::init(const std::string& addr) ...@@ -327,6 +343,19 @@ void Address::init(const std::string& addr)
host_ = "127.0.0.1"; host_ = "127.0.0.1";
} }
struct hostent *hp = ::gethostbyname(host_.c_str());
if (hp)
{
struct in_addr **addr_list;
addr_list = (struct in_addr **)hp->h_addr_list;
for(int i = 0; addr_list[i] != NULL; i++)
{
// Just take the first IP address
host_ = std::string(inet_ntoa(*addr_list[i]));
break;
}
}
if (!IsIPv4HostName(host_)) if (!IsIPv4HostName(host_))
{ {
throw std::invalid_argument("Invalid IPv4 address"); throw std::invalid_argument("Invalid IPv4 address");
...@@ -337,12 +366,26 @@ void Address::init(const std::string& addr) ...@@ -337,12 +366,26 @@ void Address::init(const std::string& addr)
const std::string& portPart = parser.rawPort(); const std::string& portPart = parser.rawPort();
if (portPart.empty()) if (portPart.empty())
{
if (parser.hasColon())
{
// "www.example.com:" or "127.0.0.1:" cases
throw std::invalid_argument("Invalid port"); throw std::invalid_argument("Invalid port");
char *end = 0; }
long port = strtol(portPart.c_str(), &end, 10); else
if (*end != 0 || port < Port::min() || port > Port::max()) {
throw std::invalid_argument("Invalid port"); // "www.example.com" or "127.0.0.1" cases
port_ = Port(port); port_ = Const::HTTP_STANDARD_PORT;
}
}
else
{
char *end = 0;
long port = strtol(portPart.c_str(), &end, 10);
if (*end != 0 || port < Port::min() || port > Port::max())
throw std::invalid_argument("Invalid port");
port_ = Port(port);
}
} }
Error::Error(const char* message) Error::Error(const char* message)
......
...@@ -81,11 +81,18 @@ TEST(net_test, address_creation) ...@@ -81,11 +81,18 @@ TEST(net_test, address_creation)
Address address13(Ipv6::loopback(), Port(8080)); Address address13(Ipv6::loopback(), Port(8080));
ASSERT_EQ(address13.host(), "::1"); ASSERT_EQ(address13.host(), "::1");
ASSERT_EQ(address13.port(), 8080); ASSERT_EQ(address13.port(), 8080);
Address address14("127.0.0.1");
ASSERT_EQ(address14.host(), "127.0.0.1");
ASSERT_EQ(address14.port(), 80);
Address address15("www.example.com");
ASSERT_EQ(address15.host(), "93.184.216.34");
ASSERT_EQ(address15.port(), 80);
} }
TEST(net_test, invalid_address) TEST(net_test, invalid_address)
{ {
ASSERT_THROW(Address("127.0.0.1"), std::invalid_argument);
ASSERT_THROW(Address("127.0.0.1:9999999"), std::invalid_argument); ASSERT_THROW(Address("127.0.0.1:9999999"), std::invalid_argument);
ASSERT_THROW(Address("127.0.0.1:"), std::invalid_argument); ASSERT_THROW(Address("127.0.0.1:"), std::invalid_argument);
ASSERT_THROW(Address("127.0.0.1:-10"), std::invalid_argument); ASSERT_THROW(Address("127.0.0.1:-10"), std::invalid_argument);
...@@ -102,11 +109,18 @@ TEST(net_test, address_parser) ...@@ -102,11 +109,18 @@ TEST(net_test, address_parser)
ASSERT_EQ(ap1.rawHost(), "127.0.0.1"); ASSERT_EQ(ap1.rawHost(), "127.0.0.1");
ASSERT_EQ(ap1.rawPort(), "80"); ASSERT_EQ(ap1.rawPort(), "80");
ASSERT_EQ(ap1.family(), AF_INET); ASSERT_EQ(ap1.family(), AF_INET);
ASSERT_EQ(ap1.hasColon(), true);
AddressParser ap2("[2001:0DB8:AABB:CCDD:EEFF:0011:2233:4455]:8080");
ASSERT_EQ(ap2.rawHost(), "[2001:0DB8:AABB:CCDD:EEFF:0011:2233:4455]"); AddressParser ap2("example.com");
ASSERT_EQ(ap2.rawPort(), "8080"); ASSERT_EQ(ap2.rawHost(), "example.com");
ASSERT_EQ(ap2.family(), AF_INET6); ASSERT_EQ(ap2.rawPort(), "");
ASSERT_EQ(ap2.family(), AF_INET);
ASSERT_EQ(ap2.hasColon(), false);
AddressParser ap3("[2001:0DB8:AABB:CCDD:EEFF:0011:2233:4455]:8080");
ASSERT_EQ(ap3.rawHost(), "[2001:0DB8:AABB:CCDD:EEFF:0011:2233:4455]");
ASSERT_EQ(ap3.rawPort(), "8080");
ASSERT_EQ(ap3.family(), AF_INET6);
ASSERT_THROW(AddressParser("127.0.0.1:");, std::invalid_argument); ASSERT_THROW(AddressParser("127.0.0.1:");, std::invalid_argument);
ASSERT_THROW(AddressParser("[::]:");, std::invalid_argument); ASSERT_THROW(AddressParser("[::]:");, std::invalid_argument);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment