bool unfilterData(
        const ByteBuffer &filteredByteBuffer,
        ByteBuffer &unfilteredByteBuffer,
        std::size_t unfilteredDataLen,
        const std::vector<FilterPtr> &filters)
    {
        ThreadLocalCached< std::vector<ByteBuffer> > tlcUnfilteredByteBuffers;
        std::vector<ByteBuffer> &unfilteredByteBuffers = tlcUnfilteredByteBuffers.get();

        bool ret = unfilterData(
            filteredByteBuffer,
            unfilteredByteBuffers,
            unfilteredDataLen,
            filters);

        if (unfilteredByteBuffers.empty())
        {
            unfilteredByteBuffer = ByteBuffer();
        }
        else if (unfilteredByteBuffers.size() == 1)
        {
            unfilteredByteBuffer = unfilteredByteBuffers[0];
        }
        else
        {
            // TODO: maybe check for adjacent buffers, in which case one should not need to make a copy
            copyByteBuffers(unfilteredByteBuffers, unfilteredByteBuffer);
        }
        return ret;
    }
Exemple #2
0
    void HttpSessionFilter::write(const std::vector<ByteBuffer> &byteBuffers)
    {
        // If we write the response directly to network here, we ar at risk of a race
        // condition as the next request may be read in on another connection, before
        // the write completion on this connection has executed.

        // So instead we make a copy of the write buffers, and send a write completion
        // back up. The subsequent read operation will unhook the HTTP session and then 
        // write the response to the network.

        if ( mNetworkSession.mCloseAfterWrite )
        {
            // Special case, if this is the last message being written before the connection closes.
            mpPostFilter->write(byteBuffers);
        }
        else
        {
            std::size_t len = lengthByteBuffers(byteBuffers);
            ReallocBufferPtr bufferPtr = getObjectPool().getReallocBufferPtr();
            bufferPtr->resize(len);
            copyByteBuffers(byteBuffers, bufferPtr->getPtr());
            mWriteBuffers.resize(0);
            mWriteBuffers.push_back(ByteBuffer(bufferPtr));

            mpPreFilter->onWriteCompleted(len);
        }
    }
Exemple #3
0
    void copyByteBuffers(
        const std::vector<ByteBuffer> &byteBuffers,
        ByteBuffer &byteBuffer)
    {
        boost::shared_ptr<std::vector<char> > vecPtr(
            new std::vector<char>(lengthByteBuffers(byteBuffers)));

        copyByteBuffers(byteBuffers, &(*vecPtr)[0]);
        byteBuffer = ByteBuffer(
            &(*vecPtr)[0],
            (*vecPtr).size(),
            vecPtr);
    }
    int UdpClientTransport::send(
        I_ClientTransportCallback &clientStub, 
        const std::vector<ByteBuffer> &data,
        unsigned int timeoutMs)
    {
        RCF_LOG_4()(mSock)(mDestIp.string()) << "UdpClientTransport - sending data on socket.";

        RCF_UNUSED_VARIABLE(timeoutMs);

        RCF_ASSERT(!mAsync);

        // TODO: optimize for case of single byte buffer with left margin

        if (mWriteVecPtr.get() == NULL || !mWriteVecPtr.unique())
        {
            mWriteVecPtr.reset( new ReallocBuffer());
        }

        mLastRequestSize = lengthByteBuffers(data);
        mRunningTotalBytesSent += lengthByteBuffers(data);

        ReallocBuffer &buffer = *mWriteVecPtr;
        buffer.resize(lengthByteBuffers(data));

        copyByteBuffers(data, &buffer[0]);

        sockaddr * pDestAddr = NULL;
        Platform::OS::BsdSockets::socklen_t destAddrSize = 0;
        mDestIp.getSockAddr(pDestAddr, destAddrSize);

        int len = sendto(
            mSock,
            &buffer[0],
            static_cast<int>(buffer.size()),
            0,
            pDestAddr, 
            destAddrSize);

        int err = Platform::OS::BsdSockets::GetLastError();
        RCF_VERIFY(
            len > 0,
            Exception(
                _RcfError_Socket("sendto()"),
                err,
                RcfSubsystem_Os));

        clientStub.onSendCompleted();

        return 1;
    }
    void UdpSessionState::postWrite(
        std::vector<ByteBuffer> &byteBuffers)
    {
        // prepend data length and send the data

        boost::shared_ptr<std::vector<char> > &writeVecPtr = mWriteVecPtr;

        if (writeVecPtr.get() == NULL || !writeVecPtr.unique())
        {
            writeVecPtr.reset( new std::vector<char>());
        }

        std::vector<char> &writeBuffer = *writeVecPtr;

        unsigned int dataLength = static_cast<unsigned int>(
            lengthByteBuffers(byteBuffers));

        writeBuffer.resize(4+dataLength);
        memcpy( &writeBuffer[0], &dataLength, 4);
        machineToNetworkOrder(&writeBuffer[0], 4, 1);
        copyByteBuffers(byteBuffers, &writeBuffer[4]);
        byteBuffers.resize(0);

        const sockaddr_in &remoteAddr = remoteAddress.getSockAddr();
       
        int len = sendto(
            mTransport.mFd,
            &writeBuffer[0],
            static_cast<int>(writeBuffer.size()),
            0,
            (const sockaddr *) &remoteAddr,
            sizeof(remoteAddr));

        if (len != static_cast<int>(writeBuffer.size()))
        {
            int err = Platform::OS::BsdSockets::GetLastError();
            RCF_THROW(Exception(
                RcfError_Socket, err, RcfSubsystem_Os, "sendto() failed"))
                (mTransport.mFd)(len)(writeBuffer.size());
        }

        SessionStatePtr sessionStatePtr = getCurrentUdpSessionStatePtr();

        SessionPtr sessionPtr = sessionStatePtr->mSessionPtr;

        RcfSessionPtr rcfSessionPtr = 
            boost::static_pointer_cast<RcfSession>(sessionPtr);

        rcfSessionPtr->mIoState = RcfSession::Reading;
    }
    void UdpSessionState::postWrite(
        std::vector<ByteBuffer> &byteBuffers)
    {
        // prepend data length and send the data

        ReallocBufferPtr &writeVecPtr = mWriteVecPtr;

        if (writeVecPtr.get() == NULL || !writeVecPtr.unique())
        {
            writeVecPtr.reset( new ReallocBuffer());
        }

        ReallocBuffer &writeBuffer = *writeVecPtr;

        unsigned int dataLength = static_cast<unsigned int>(
            lengthByteBuffers(byteBuffers));

        writeBuffer.resize(4+dataLength);
        memcpy( &writeBuffer[0], &dataLength, 4);
        machineToNetworkOrder(&writeBuffer[0], 4, 1);
        copyByteBuffers(byteBuffers, &writeBuffer[4]);
        byteBuffers.resize(0);

        sockaddr * pRemoteAddr = NULL;
        Platform::OS::BsdSockets::socklen_t remoteAddrSize = 0;
        mRemoteAddress.getSockAddr(pRemoteAddr, remoteAddrSize);
       
        int len = sendto(
            mTransport.mFd,
            &writeBuffer[0],
            static_cast<int>(writeBuffer.size()),
            0,
            pRemoteAddr,
            remoteAddrSize);

        if (len != static_cast<int>(writeBuffer.size()))
        {
            int err = Platform::OS::BsdSockets::GetLastError();
            Exception e(_RcfError_Socket("sendto()"), err, RcfSubsystem_Os);
            RCF_THROW(e)(mTransport.mFd)(len)(writeBuffer.size());
        }

        SessionStatePtr sessionStatePtr = getTlsUdpSessionStatePtr();

        SessionPtr sessionPtr = sessionStatePtr->mSessionPtr;
    }