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
#include <cstddef>
#include <cstdint>
// Allow compile-time overload
namespace Pistache
......@@ -17,5 +18,7 @@ namespace Const
// Defined from CMakeLists.txt in project root
static constexpr size_t DefaultMaxPayload = 4096;
static constexpr size_t ChunkSize = 1024;
static constexpr uint16_t HTTP_STANDARD_PORT = 80;
} // namespace Const
} // namespace Pistache
\ No newline at end of file
......@@ -119,7 +119,6 @@ namespace Http {
CHARSET(Utf32-LE, "utf-32le") \
CHARSET(Unicode-11, "unicode-1-1")
const uint16_t HTTP_STANDARD_PORT = 80;
enum class Method {
#define METHOD(m, _) m,
......
......@@ -128,11 +128,13 @@ public:
explicit AddressParser(const std::string& data);
const std::string& rawHost() const;
const std::string& rawPort() const;
bool hasColon() const;
int family() const;
private:
std::string host_;
std::string port_;
int family_;
bool hasColon_ = false;
int family_ = 0;
};
class Address {
......
......@@ -6,6 +6,7 @@
#include <pistache/http_header.h>
#include <pistache/common.h>
#include <pistache/config.h>
#include <pistache/http.h>
#include <pistache/stream.h>
......@@ -342,7 +343,7 @@ void Host::parse(const std::string& data)
const std::string& port = parser.rawPort();
if (port.empty())
{
port_ = HTTP_STANDARD_PORT;
port_ = Const::HTTP_STANDARD_PORT;
}
else
{
......
......@@ -5,6 +5,7 @@
#include <pistache/net.h>
#include <pistache/common.h>
#include <pistache/config.h>
#include <stdexcept>
#include <limits>
......@@ -195,13 +196,23 @@ AddressParser::AddressParser(const std::string& data)
end_pos != std::string::npos &&
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);
family_ = AF_INET6;
++end_pos;
}
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);
family_ = AF_INET;
}
......@@ -224,6 +235,11 @@ const std::string& AddressParser::rawPort() const
return port_;
}
bool AddressParser::hasColon() const
{
return hasColon_;
}
int AddressParser::family() const
{
return family_;
......@@ -327,6 +343,19 @@ void Address::init(const std::string& addr)
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_))
{
throw std::invalid_argument("Invalid IPv4 address");
......@@ -337,12 +366,26 @@ void Address::init(const std::string& addr)
const std::string& portPart = parser.rawPort();
if (portPart.empty())
{
if (parser.hasColon())
{
// "www.example.com:" or "127.0.0.1:" cases
throw std::invalid_argument("Invalid port");
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);
}
else
{
// "www.example.com" or "127.0.0.1" cases
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)
......
......@@ -81,11 +81,18 @@ TEST(net_test, address_creation)
Address address13(Ipv6::loopback(), Port(8080));
ASSERT_EQ(address13.host(), "::1");
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)
{
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:"), std::invalid_argument);
ASSERT_THROW(Address("127.0.0.1:-10"), std::invalid_argument);
......@@ -102,11 +109,18 @@ TEST(net_test, address_parser)
ASSERT_EQ(ap1.rawHost(), "127.0.0.1");
ASSERT_EQ(ap1.rawPort(), "80");
ASSERT_EQ(ap1.family(), AF_INET);
AddressParser ap2("[2001:0DB8:AABB:CCDD:EEFF:0011:2233:4455]:8080");
ASSERT_EQ(ap2.rawHost(), "[2001:0DB8:AABB:CCDD:EEFF:0011:2233:4455]");
ASSERT_EQ(ap2.rawPort(), "8080");
ASSERT_EQ(ap2.family(), AF_INET6);
ASSERT_EQ(ap1.hasColon(), true);
AddressParser ap2("example.com");
ASSERT_EQ(ap2.rawHost(), "example.com");
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("[::]:");, 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