can create a socket from a fd
This commit is contained in:
		@@ -37,8 +37,8 @@
 | 
			
		||||
 | 
			
		||||
namespace ix 
 | 
			
		||||
{
 | 
			
		||||
    Socket::Socket() : 
 | 
			
		||||
        _sockfd(-1)
 | 
			
		||||
    Socket::Socket(int fd) : 
 | 
			
		||||
        _sockfd(fd)
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@ namespace ix
 | 
			
		||||
    public:
 | 
			
		||||
        using OnPollCallback = std::function<void()>;
 | 
			
		||||
 | 
			
		||||
        Socket();
 | 
			
		||||
        Socket(int fd = -1);
 | 
			
		||||
        virtual ~Socket();
 | 
			
		||||
 | 
			
		||||
        void configure();
 | 
			
		||||
 
 | 
			
		||||
@@ -143,7 +143,7 @@ std::string getSSLErrorDescription(OSStatus status)
 | 
			
		||||
 | 
			
		||||
namespace ix 
 | 
			
		||||
{
 | 
			
		||||
    SocketAppleSSL::SocketAppleSSL() : 
 | 
			
		||||
    SocketAppleSSL::SocketAppleSSL(int fd) : Socket(fd),
 | 
			
		||||
        _sslContext(nullptr)
 | 
			
		||||
    {
 | 
			
		||||
        ;
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@ namespace ix
 | 
			
		||||
    class SocketAppleSSL : public Socket 
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        SocketAppleSSL();
 | 
			
		||||
        SocketAppleSSL(int fd = -1);
 | 
			
		||||
        ~SocketAppleSSL();
 | 
			
		||||
 | 
			
		||||
        virtual bool connect(const std::string& host, 
 | 
			
		||||
 
 | 
			
		||||
@@ -74,7 +74,7 @@ SSL *openssl_create_connection(SSL_CTX *ctx, int socket)
 | 
			
		||||
 | 
			
		||||
namespace ix 
 | 
			
		||||
{
 | 
			
		||||
    SocketOpenSSL::SocketOpenSSL() :
 | 
			
		||||
    SocketOpenSSL::SocketOpenSSL(int fd) : Socket(fd),
 | 
			
		||||
        _ssl_connection(nullptr), 
 | 
			
		||||
        _ssl_context(nullptr)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@ namespace ix
 | 
			
		||||
    class SocketOpenSSL : public Socket 
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        SocketOpenSSL();
 | 
			
		||||
        SocketOpenSSL(int fd = -1);
 | 
			
		||||
        ~SocketOpenSSL();
 | 
			
		||||
 | 
			
		||||
        virtual bool connect(const std::string& host, 
 | 
			
		||||
 
 | 
			
		||||
@@ -145,6 +145,59 @@ namespace ix
 | 
			
		||||
        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 alphanum = 
 | 
			
		||||
@@ -247,6 +300,7 @@ namespace ix
 | 
			
		||||
            return WebSocketInitResult(false, 0, std::string("Failed sending GET request to ") + _url);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Read first line
 | 
			
		||||
        char line[256];
 | 
			
		||||
        int 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());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        WebSocketHttpHeaders headers;
 | 
			
		||||
        auto result = parseHttpHeaders();
 | 
			
		||||
        auto headersValid = result.first;
 | 
			
		||||
        auto headers = result.second;
 | 
			
		||||
 | 
			
		||||
        while (true) 
 | 
			
		||||
        if (!headersValid)
 | 
			
		||||
        {
 | 
			
		||||
            int colon = 0;
 | 
			
		||||
 | 
			
		||||
            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;
 | 
			
		||||
            }
 | 
			
		||||
            return WebSocketInitResult(false, status, "Error parsing HTTP headers");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        char output[29] = {};
 | 
			
		||||
@@ -362,6 +380,15 @@ namespace ix
 | 
			
		||||
        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 
 | 
			
		||||
    {
 | 
			
		||||
        return _readyState;
 | 
			
		||||
 
 | 
			
		||||
@@ -74,10 +74,14 @@ namespace ix
 | 
			
		||||
        WebSocketTransport();
 | 
			
		||||
        ~WebSocketTransport();
 | 
			
		||||
 | 
			
		||||
        // Client
 | 
			
		||||
        void configure(const std::string& url,
 | 
			
		||||
                       const WebSocketPerMessageDeflateOptions& perMessageDeflateOptions);
 | 
			
		||||
        WebSocketInitResult init();
 | 
			
		||||
 | 
			
		||||
        // Server
 | 
			
		||||
        WebSocketInitResult initFromSocket(int fd);
 | 
			
		||||
 | 
			
		||||
        void poll();
 | 
			
		||||
        WebSocketSendInfo sendBinary(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
 | 
			
		||||
        bool readByte(void* buffer);
 | 
			
		||||
        bool writeBytes(const std::string& str);
 | 
			
		||||
 | 
			
		||||
        // Parse HTTP headers
 | 
			
		||||
        std::pair<bool, WebSocketHttpHeaders> parseHttpHeaders();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user