Added some basic HTTP and ip address parsing.

This commit is contained in:
2024-08-18 23:06:09 +02:00
parent 03c899f17e
commit 35e7131780
9 changed files with 497 additions and 35 deletions

View File

@@ -4,7 +4,10 @@
#if !defined(MIJIN_NET_SOCKET_HPP_INCLUDED)
#define MIJIN_NET_SOCKET_HPP_INCLUDED 1
#include <array>
#include <variant>
#include "../async/coroutine.hpp"
#include "../container/optional.hpp"
#include "../io/stream.hpp"
namespace mijin
@@ -14,6 +17,41 @@ namespace mijin
// public types
//
struct IPv4Address
{
std::array<std::uint8_t, 4> octets;
auto operator<=>(const IPv4Address&) const noexcept = default;
[[nodiscard]]
static Optional<IPv4Address> fromString(std::string_view stringView) noexcept;
};
struct IPv6Address
{
std::array<std::uint16_t, 8> hextets;
auto operator<=>(const IPv6Address&) const noexcept = default;
[[nodiscard]]
static Optional<IPv6Address> fromString(std::string_view stringView) noexcept;
};
using ip_address_t = std::variant<IPv4Address, IPv6Address>;
[[nodiscard]]
inline Optional<ip_address_t> ipAddressFromString(std::string_view stringView) noexcept
{
if (Optional<IPv4Address> ipv4Address = IPv4Address::fromString(stringView); !ipv4Address.empty())
{
return ip_address_t(*ipv4Address);
}
if (Optional<IPv6Address> ipv6Address = IPv6Address::fromString(stringView); !ipv6Address.empty())
{
return ip_address_t(*ipv6Address);
}
return NULL_OPTIONAL;
}
class Socket
{
protected:
@@ -61,7 +99,7 @@ public:
bool isAtEnd() override;
StreamFeatures getFeatures() override;
StreamError open(const char* address, std::uint16_t port) noexcept;
StreamError open(ip_address_t address, std::uint16_t port) noexcept;
void close() noexcept;
[[nodiscard]] bool isOpen() const noexcept { return handle_ >= 0; }
private:
@@ -77,7 +115,15 @@ private:
public:
TCPStream& getStream() noexcept override;
StreamError open(const char* address, std::uint16_t port) noexcept { return stream_.open(address, port); }
StreamError open(ip_address_t address, std::uint16_t port) noexcept { return stream_.open(address, port); }
StreamError open(std::string_view addressText, std::uint16_t port) noexcept
{
if (Optional<ip_address_t> address = ipAddressFromString(addressText); !address.empty())
{
return open(*address, port);
}
return StreamError::UNKNOWN_ERROR;
}
void close() noexcept { stream_.close(); }
[[nodiscard]] bool isOpen() const noexcept { return stream_.isOpen(); }