can create a socket from a fd
This commit is contained in:
parent
43cd6d34ca
commit
ea07afcc0b
@ -37,8 +37,8 @@
|
|||||||
|
|
||||||
namespace ix
|
namespace ix
|
||||||
{
|
{
|
||||||
Socket::Socket() :
|
Socket::Socket(int fd) :
|
||||||
_sockfd(-1)
|
_sockfd(fd)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ namespace ix
|
|||||||
public:
|
public:
|
||||||
using OnPollCallback = std::function<void()>;
|
using OnPollCallback = std::function<void()>;
|
||||||
|
|
||||||
Socket();
|
Socket(int fd = -1);
|
||||||
virtual ~Socket();
|
virtual ~Socket();
|
||||||
|
|
||||||
void configure();
|
void configure();
|
||||||
|
@ -143,7 +143,7 @@ std::string getSSLErrorDescription(OSStatus status)
|
|||||||
|
|
||||||
namespace ix
|
namespace ix
|
||||||
{
|
{
|
||||||
SocketAppleSSL::SocketAppleSSL() :
|
SocketAppleSSL::SocketAppleSSL(int fd) : Socket(fd),
|
||||||
_sslContext(nullptr)
|
_sslContext(nullptr)
|
||||||
{
|
{
|
||||||
;
|
;
|
||||||
|
@ -19,7 +19,7 @@ namespace ix
|
|||||||
class SocketAppleSSL : public Socket
|
class SocketAppleSSL : public Socket
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SocketAppleSSL();
|
SocketAppleSSL(int fd = -1);
|
||||||
~SocketAppleSSL();
|
~SocketAppleSSL();
|
||||||
|
|
||||||
virtual bool connect(const std::string& host,
|
virtual bool connect(const std::string& host,
|
||||||
|
@ -74,7 +74,7 @@ SSL *openssl_create_connection(SSL_CTX *ctx, int socket)
|
|||||||
|
|
||||||
namespace ix
|
namespace ix
|
||||||
{
|
{
|
||||||
SocketOpenSSL::SocketOpenSSL() :
|
SocketOpenSSL::SocketOpenSSL(int fd) : Socket(fd),
|
||||||
_ssl_connection(nullptr),
|
_ssl_connection(nullptr),
|
||||||
_ssl_context(nullptr)
|
_ssl_context(nullptr)
|
||||||
{
|
{
|
||||||
|
@ -22,7 +22,7 @@ namespace ix
|
|||||||
class SocketOpenSSL : public Socket
|
class SocketOpenSSL : public Socket
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SocketOpenSSL();
|
SocketOpenSSL(int fd = -1);
|
||||||
~SocketOpenSSL();
|
~SocketOpenSSL();
|
||||||
|
|
||||||
virtual bool connect(const std::string& host,
|
virtual bool connect(const std::string& host,
|
||||||
|
@ -145,6 +145,59 @@ namespace ix
|
|||||||
std::cout << "-------------------------------" << std::endl;
|
std::cout << "-------------------------------" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<bool, WebSocketHttpHeaders> WebSocketTransport::parseHttpHeaders()
|
||||||
|
{
|
||||||
|
WebSocketHttpHeaders headers;
|
||||||
|
|
||||||
|
char line[256];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
int colon = 0;
|
||||||
|
|
||||||
|
for (i = 0;
|
||||||
|
i < 2 || (i < 255 && line[i-2] != '\r' && line[i-1] != '\n');
|
||||||
|
++i)
|
||||||
|
{
|
||||||
|
if (!readByte(line+i))
|
||||||
|
{
|
||||||
|
return std::make_pair(false, headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line[i] == ':' && colon == 0)
|
||||||
|
{
|
||||||
|
colon = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (line[0] == '\r' && line[1] == '\n')
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// line is a single header entry. split by ':', and add it to our
|
||||||
|
// header map. ignore lines with no colon.
|
||||||
|
if (colon > 0)
|
||||||
|
{
|
||||||
|
line[i] = '\0';
|
||||||
|
std::string lineStr(line);
|
||||||
|
// colon is ':', colon+1 is ' ', colon+2 is the start of the value.
|
||||||
|
// i is end of string (\0), i-colon is length of string minus key;
|
||||||
|
// subtract 1 for '\0', 1 for '\n', 1 for '\r',
|
||||||
|
// 1 for the ' ' after the ':', and total is -4
|
||||||
|
std::string name(lineStr.substr(0, colon));
|
||||||
|
std::string value(lineStr.substr(colon + 2, i - colon - 4));
|
||||||
|
|
||||||
|
// Make the name lower case.
|
||||||
|
std::transform(name.begin(), name.end(), name.begin(), ::tolower);
|
||||||
|
|
||||||
|
headers[name] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_pair(true, headers);
|
||||||
|
}
|
||||||
|
|
||||||
std::string WebSocketTransport::genRandomString(const int len)
|
std::string WebSocketTransport::genRandomString(const int len)
|
||||||
{
|
{
|
||||||
std::string alphanum =
|
std::string alphanum =
|
||||||
@ -247,6 +300,7 @@ namespace ix
|
|||||||
return WebSocketInitResult(false, 0, std::string("Failed sending GET request to ") + _url);
|
return WebSocketInitResult(false, 0, std::string("Failed sending GET request to ") + _url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read first line
|
||||||
char line[256];
|
char line[256];
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 2 || (i < 255 && line[i-2] != '\r' && line[i-1] != '\n'); ++i)
|
for (i = 0; i < 2 || (i < 255 && line[i-2] != '\r' && line[i-1] != '\n'); ++i)
|
||||||
@ -285,49 +339,13 @@ namespace ix
|
|||||||
return WebSocketInitResult(false, status, ss.str());
|
return WebSocketInitResult(false, status, ss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
WebSocketHttpHeaders headers;
|
auto result = parseHttpHeaders();
|
||||||
|
auto headersValid = result.first;
|
||||||
|
auto headers = result.second;
|
||||||
|
|
||||||
while (true)
|
if (!headersValid)
|
||||||
{
|
{
|
||||||
int colon = 0;
|
return WebSocketInitResult(false, status, "Error parsing HTTP headers");
|
||||||
|
|
||||||
for (i = 0;
|
|
||||||
i < 2 || (i < 255 && line[i-2] != '\r' && line[i-1] != '\n');
|
|
||||||
++i)
|
|
||||||
{
|
|
||||||
if (!readByte(line+i))
|
|
||||||
{
|
|
||||||
return WebSocketInitResult(false, status, std::string("Failed reading response header from ") + _url);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line[i] == ':' && colon == 0)
|
|
||||||
{
|
|
||||||
colon = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (line[0] == '\r' && line[1] == '\n')
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// line is a single header entry. split by ':', and add it to our
|
|
||||||
// header map. ignore lines with no colon.
|
|
||||||
if (colon > 0)
|
|
||||||
{
|
|
||||||
line[i] = '\0';
|
|
||||||
std::string lineStr(line);
|
|
||||||
// colon is ':', colon+1 is ' ', colon+2 is the start of the value.
|
|
||||||
// i is end of string (\0), i-colon is length of string minus key;
|
|
||||||
// subtract 1 for '\0', 1 for '\n', 1 for '\r',
|
|
||||||
// 1 for the ' ' after the ':', and total is -4
|
|
||||||
std::string name(lineStr.substr(0, colon));
|
|
||||||
std::string value(lineStr.substr(colon + 2, i - colon - 4));
|
|
||||||
|
|
||||||
// Make the name lower case.
|
|
||||||
std::transform(name.begin(), name.end(), name.begin(), ::tolower);
|
|
||||||
|
|
||||||
headers[name] = value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char output[29] = {};
|
char output[29] = {};
|
||||||
@ -362,6 +380,15 @@ namespace ix
|
|||||||
return WebSocketInitResult(true, status, "", headers);
|
return WebSocketInitResult(true, status, "", headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WebSocketInitResult WebSocketTransport::initFromSocket(int fd)
|
||||||
|
{
|
||||||
|
_socket.reset();
|
||||||
|
_socket = std::make_shared<Socket>(fd);
|
||||||
|
|
||||||
|
WebSocketHttpHeaders headers;
|
||||||
|
return WebSocketInitResult(true, 200, "", headers);
|
||||||
|
}
|
||||||
|
|
||||||
WebSocketTransport::ReadyStateValues WebSocketTransport::getReadyState() const
|
WebSocketTransport::ReadyStateValues WebSocketTransport::getReadyState() const
|
||||||
{
|
{
|
||||||
return _readyState;
|
return _readyState;
|
||||||
|
@ -74,10 +74,14 @@ namespace ix
|
|||||||
WebSocketTransport();
|
WebSocketTransport();
|
||||||
~WebSocketTransport();
|
~WebSocketTransport();
|
||||||
|
|
||||||
|
// Client
|
||||||
void configure(const std::string& url,
|
void configure(const std::string& url,
|
||||||
const WebSocketPerMessageDeflateOptions& perMessageDeflateOptions);
|
const WebSocketPerMessageDeflateOptions& perMessageDeflateOptions);
|
||||||
WebSocketInitResult init();
|
WebSocketInitResult init();
|
||||||
|
|
||||||
|
// Server
|
||||||
|
WebSocketInitResult initFromSocket(int fd);
|
||||||
|
|
||||||
void poll();
|
void poll();
|
||||||
WebSocketSendInfo sendBinary(const std::string& message);
|
WebSocketSendInfo sendBinary(const std::string& message);
|
||||||
WebSocketSendInfo sendPing(const std::string& message);
|
WebSocketSendInfo sendPing(const std::string& message);
|
||||||
@ -164,5 +168,8 @@ namespace ix
|
|||||||
// Non blocking versions of read/write, used during http upgrade
|
// Non blocking versions of read/write, used during http upgrade
|
||||||
bool readByte(void* buffer);
|
bool readByte(void* buffer);
|
||||||
bool writeBytes(const std::string& str);
|
bool writeBytes(const std::string& str);
|
||||||
|
|
||||||
|
// Parse HTTP headers
|
||||||
|
std::pair<bool, WebSocketHttpHeaders> parseHttpHeaders();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user