can create a socket from a fd
This commit is contained in:
		@@ -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();
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user