HttpsClientTransport::HttpsClientTransport(const HttpsEndpoint & httpsEndpoint) : 
        TcpClientTransport(httpsEndpoint.getIp(), httpsEndpoint.getPort())
    {
        std::vector<FilterPtr> wireFilters;

        // HTTP framing.
        wireFilters.push_back( FilterPtr( new HttpFrameFilter(
            getRemoteAddr().getIp(), 
            getRemoteAddr().getPort())));

        // SSL.
        ClientStub * pClientStub = getTlsClientStubPtr();
        RCF_ASSERT(pClientStub);

        FilterPtr sslFilterPtr;

#if RCF_FEATURE_SSPI==1 && RCF_FEATURE_OPENSSL==1

        if (pClientStub->getSslImplementation() == Si_Schannel)
        {
            sslFilterPtr.reset( new SchannelFilter(pClientStub) );
        }
        else
        {
            RCF_ASSERT(pClientStub->getSslImplementation() == Si_OpenSsl);
            sslFilterPtr.reset( new OpenSslEncryptionFilter(pClientStub) );
        }

#elif RCF_FEATURE_SSPI==1

        sslFilterPtr.reset( new SchannelFilter(pClientStub) );

#elif RCF_FEATURE_OPENSSL==1

        sslFilterPtr.reset( new OpenSslEncryptionFilter(pClientStub) );

#endif

        if (!sslFilterPtr)
        {
            RCF_THROW( Exception(_RcfError_SslNotSupported()) );
        }

        wireFilters.push_back(sslFilterPtr);

        // HTTP CONNECT filter for passing through a proxy.
        wireFilters.push_back( FilterPtr( new HttpConnectFilter(
            getRemoteAddr().getIp(), 
            getRemoteAddr().getPort())));

        setWireFilters(wireFilters);
    }
Пример #2
0
    int getRuntimeVersionOfThisRemoteCall()
    {
        int runtimeVersion = 0;
        RcfSession * pRcfSession = getTlsRcfSessionPtr();
        ClientStub * pClientStub = getTlsClientStubPtr();
        if (pRcfSession)
        {
            runtimeVersion = pRcfSession->getRuntimeVersion();
        }
        else if (pClientStub)
        {
            runtimeVersion = pClientStub->getRuntimeVersion();
        }
        else
        {
            // This function must be called from within the client-side
            // or server-side portion of a remote call.
            RCF_ASSERT(0);
            runtimeVersion = getDefaultRuntimeVersion();
        }

        return runtimeVersion;
    }
    std::size_t Win32NamedPipeClientTransport::implRead(
        const ByteBuffer &byteBuffer,
        std::size_t bytesRequested)
    {
        // For now, can't go back to sync calls after doing an async call.
        // Limitations with Windows IOCP.
        RCF_ASSERT(!mAsyncMode);

        std::size_t bytesToRead = RCF_MIN(bytesRequested, byteBuffer.getLength());

        BOOL ok = ResetEvent(mhEvent);
        DWORD dwErr = GetLastError();
        RCF_VERIFY(ok, Exception(_RcfError_Pipe(), dwErr));

        OVERLAPPED overlapped = {0};
        overlapped.hEvent = mhEvent;

        DWORD dwRead = 0;
        DWORD dwBytesToRead = static_cast<DWORD>(bytesToRead);

        ok = ReadFile(
            mhPipe, 
            byteBuffer.getPtr(), 
            dwBytesToRead, 
            &dwRead, 
            &overlapped);
        
        dwErr = GetLastError();

        if (!ok)
        {
            RCF_VERIFY( 
                dwErr == ERROR_IO_PENDING ||
                dwErr == WSA_IO_PENDING ||
                dwErr == ERROR_MORE_DATA,
                Exception(_RcfError_ClientReadFail(), dwErr));
        }

        ClientStub & clientStub = *getTlsClientStubPtr();

        DWORD dwRet = WAIT_TIMEOUT;
        while (dwRet == WAIT_TIMEOUT)
        {
            boost::uint32_t timeoutMs = generateTimeoutMs(mEndTimeMs);
            timeoutMs = clientStub.generatePollingTimeout(timeoutMs);

            dwRet = WaitForSingleObject(overlapped.hEvent, timeoutMs);
            dwErr = GetLastError();

            RCF_VERIFY( 
                dwRet == WAIT_OBJECT_0 || dwRet == WAIT_TIMEOUT, 
                Exception(_RcfError_Pipe(), dwErr));

            RCF_VERIFY(
                generateTimeoutMs(mEndTimeMs),
                Exception(_RcfError_ClientReadTimeout()))
                (mEndTimeMs)(bytesToRead);

            if (dwRet == WAIT_TIMEOUT)
            {
                clientStub.onPollingTimeout();
            }
        }
        RCF_ASSERT_EQ(dwRet , WAIT_OBJECT_0);

        dwRead = 0;
        ok = GetOverlappedResult(mhPipe, &overlapped, &dwRead, FALSE);
        dwErr = GetLastError();
        RCF_VERIFY(ok && dwRead > 0, Exception(_RcfError_Pipe(), dwErr));

        onTimedRecvCompleted(dwRead, 0);

        return dwRead;
    }
Пример #4
0
    // return -2 for timeout, -1 for error, 0 for ready
    int pollSocket(unsigned int endTimeMs, int fd, int &err, bool bRead)
    {
        ClientStub & clientStub = *getTlsClientStubPtr();

        while (true)
        {

            fd_set fdSet;
            FD_ZERO(&fdSet);
            FD_SET( static_cast<SOCKET>(fd), &fdSet);
            
            unsigned int timeoutMs = generateTimeoutMs(endTimeMs);
            timeoutMs = clientStub.generatePollingTimeout(timeoutMs);
            
            timeval timeout = {0};
            timeout.tv_sec = timeoutMs/1000;
            timeout.tv_usec = 1000*(timeoutMs%1000);
            RCF_ASSERT_GTEQ(timeout.tv_usec , 0);
            
            int selectRet = bRead ?
                Platform::OS::BsdSockets::select(fd+1, &fdSet, NULL, NULL, &timeout) :
                Platform::OS::BsdSockets::select(fd+1, NULL, &fdSet, NULL, &timeout);
            
            err = Platform::OS::BsdSockets::GetLastError();

            // Handle timeout.
            if (selectRet == 0)
            {
                clientStub.onPollingTimeout();

                if (generateTimeoutMs(endTimeMs) != 0)
                {
                    continue;
                }
            }

            // Some socket gymnastics to determine whether a nonblocking connect 
            // has failed or not.
            if (selectRet == 1 && !bRead)
            {
                int errorOpt = 0;
                Platform::OS::BsdSockets::socklen_t len = sizeof(int); 
                int ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*)(&errorOpt), &len);
                err = Platform::OS::BsdSockets::GetLastError();

                RCF_VERIFY(
                    ret == 0, 
                    Exception(_RcfError_Socket("getsockopt()"), err, RcfSubsystem_Os));

                if (errorOpt == 0)
                {
                    return 0;
                }
                else if (   errorOpt == Platform::OS::BsdSockets::ERR_EWOULDBLOCK
                        ||  errorOpt == Platform::OS::BsdSockets::ERR_EINPROGRESS)
                {
                    continue;
                }
                else
                { 
                    err = errorOpt;
                    return -1;
                }
            }

            switch (selectRet)
            {
            case 0:  return -2;
            case 1:  return  0;
            default: return -1;
            };
        }
    }