コード例 #1
0
    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;
    }
コード例 #2
0
    void RcfSession::onWriteCompleted()
    {
        RCF_LOG_3()(this) << "RcfServer - completed sending of response.";

        {
            Lock lock(mIoStateMutex);

            if (mWritingPingBack)
            {
                mWritingPingBack = false;

                typedef std::vector<ByteBuffer> ByteBuffers;
                ThreadLocalCached< ByteBuffers > tlcQueuedBuffers;
                ByteBuffers & queuedBuffers = tlcQueuedBuffers.get();

                queuedBuffers = mQueuedSendBuffers;
                mQueuedSendBuffers.clear();
                if (!queuedBuffers.empty())
                {
                    lock.unlock();
                    getSessionState().postWrite(queuedBuffers);
                    RCF_ASSERT(queuedBuffers.empty());
                }

                return;
            }
        }

        typedef std::vector<RcfSession::OnWriteCompletedCallback> OnWriteCompletedCallbacks;
        ThreadLocalCached< OnWriteCompletedCallbacks > tlcOwcc;
        OnWriteCompletedCallbacks &onWriteCompletedCallbacks = tlcOwcc.get();
        
        extractOnWriteCompletedCallbacks(onWriteCompletedCallbacks);

        std::for_each(
            onWriteCompletedCallbacks.begin(),
            onWriteCompletedCallbacks.end(),
            boost::bind(
                &RcfSession::OnWriteCompletedCallback::operator(),
                _1,
                boost::ref(*this)));

        onWriteCompletedCallbacks.resize(0);

        mIn.clear();
        mOut.clear();

        if (!mCloseSessionAfterWrite)
        {
            getSessionState().postRead();
        }        
    }
コード例 #3
0
    bool filterData(
        const std::vector<ByteBuffer> &unfilteredData,
        std::vector<ByteBuffer> &filteredData,
        const std::vector<FilterPtr> &filters)
    {
        std::size_t bytesTransferred        = 0;
        std::size_t bytesTransferredTotal   = 0;

        WriteProxy writeProxy;
        writeProxy.setPreFilter(*filters.back());
        filters.back()->setPostFilter(writeProxy);
        filters.front()->setPreFilter(writeProxy);

        std::size_t unfilteredDataLen = lengthByteBuffers(unfilteredData);
        while (bytesTransferredTotal < unfilteredDataLen)
        {

            ThreadLocalCached< std::vector<ByteBuffer> > tlcSlicedByteBuffers;
            std::vector<ByteBuffer> &slicedByteBuffers = tlcSlicedByteBuffers.get();
            sliceByteBuffers(slicedByteBuffers, unfilteredData, bytesTransferredTotal);
            filters.front()->write(slicedByteBuffers);

            // TODO: error handling
            bytesTransferred = writeProxy.getBytesTransferred();
            bytesTransferredTotal += bytesTransferred;
        }
        RCF_ASSERT_EQ(bytesTransferredTotal , unfilteredDataLen);

        filteredData.resize(0);

        std::copy(
            writeProxy.getByteBuffers().begin(),
            writeProxy.getByteBuffers().end(),
            std::back_inserter(filteredData));

        return bytesTransferredTotal == unfilteredDataLen;
    }
コード例 #4
0
    void RcfSession::sendSessionResponse()
    {
        mIn.clearByteBuffer();

        ThreadLocalCached< std::vector<ByteBuffer> > tlcByteBuffers;
        std::vector<ByteBuffer> &byteBuffers = tlcByteBuffers.get();

        mOut.extractByteBuffers(byteBuffers);
        const std::vector<FilterPtr> &filters = mFilters;
        ThreadLocalCached< std::vector<ByteBuffer> > tlcEncodedByteBuffers;
        std::vector<ByteBuffer> &encodedByteBuffers = tlcEncodedByteBuffers.get();

        ThreadLocalCached< std::vector<FilterPtr> > tlcNoFilters;
        std::vector<FilterPtr> &noFilters = tlcNoFilters.get();

        mRequest.encodeToMessage(
            encodedByteBuffers, 
            byteBuffers, 
            mFiltered ? filters : noFilters);

        RCF_LOG_3()(this)(lengthByteBuffers(byteBuffers))(lengthByteBuffers(encodedByteBuffers))
            << "RcfServer - sending response.";

        byteBuffers.resize(0);

        bool okToWrite = false;
        {
            Lock lock(mIoStateMutex);
            unregisterForPingBacks();
            if (mWritingPingBack)
            {
                mQueuedSendBuffers = encodedByteBuffers;
                encodedByteBuffers.resize(0);
                byteBuffers.resize(0);
            }
            else
            {
                okToWrite = true;
            }
        }

        if (okToWrite)
        {
            getSessionState().postWrite(encodedByteBuffers);
            RCF_ASSERT(encodedByteBuffers.empty());
            RCF_ASSERT(byteBuffers.empty());
        }

        setTlsRcfSessionPtr();
    }
コード例 #5
0
    // returns -2 for timeout, -1 for error, otherwise number of bytes sent (> 0)
    int timedSend(
        I_PollingFunctor &pollingFunctor,
        int &err,
        int fd,
        const std::vector<ByteBuffer> &byteBuffers,
        std::size_t maxSendSize,
        int flags)
    {
        RCF_UNUSED_VARIABLE(flags);
        std::size_t bytesRemaining = lengthByteBuffers(byteBuffers);
        std::size_t bytesSent = 0;
        while (true)
        {
            std::size_t bytesToSend = RCF_MIN(bytesRemaining, maxSendSize);

            ThreadLocalCached< std::vector<WSABUF> > tlcWsabufs;
            std::vector<WSABUF> &wsabufs = tlcWsabufs.get();

            forEachByteBuffer(
                boost::bind(&appendWsabuf, boost::ref(wsabufs), _1),
                byteBuffers,
                bytesSent,
                bytesToSend);

            int count = 0;
            int myErr = 0;

#ifdef BOOST_WINDOWS
            {
                DWORD cbSent = 0;
                int ret = WSASend(
                    fd, 
                    &wsabufs[0], 
                    static_cast<DWORD>(wsabufs.size()), 
                    &cbSent, 
                    0, 
                    NULL, 
                    NULL);

                count = (ret == 0) ? cbSent : -1;
                myErr = Platform::OS::BsdSockets::GetLastError();
            }            
#else
            {
                msghdr hdr = {0};
                hdr.msg_iov = &wsabufs[0];
                hdr.msg_iovlen = wsabufs.size();
                count = sendmsg(fd, &hdr, 0);
                myErr = Platform::OS::BsdSockets::GetLastError();
            }
#endif

            if (count >= 0)
            {
                RCF_ASSERT_LTEQ(count , static_cast<int>(bytesRemaining));

                bytesRemaining -= count;
                bytesSent += count;
                err = 0;
                return static_cast<int>(bytesSent);
            }
            else if (myErr == Platform::OS::BsdSockets::ERR_EWOULDBLOCK)
            {
                // can't get WSA_IO_PENDING here, since the socket isn't overlapped
                int ret = pollingFunctor(fd, myErr, false);
                if (ret  != 0)
                {
                    err = myErr;
                    return ret;
                }
            }
            else
            {
                err = myErr;
                return -1;
            }


        }
    }
コード例 #6
0
    void RcfSession::processJsonRpcRequest()
    {
        ByteBuffer readByteBuffer = getSessionState().getReadByteBuffer();

        RCF_LOG_3()(this)(readByteBuffer.getLength()) 
            << "RcfServer - received JSON-RPC packet from transport.";

        CurrentRcfSessionSentry guard(*this);

        boost::scoped_ptr<JsonRpcResponse> jsonResponsePtr;
        bool isOneway = false;
        boost::uint64_t jsonRequestId = 0;

        try
        {
            JsonRpcRequest jsonRequest(readByteBuffer);
            jsonRequestId = jsonRequest.getRequestId();
            jsonResponsePtr.reset( new JsonRpcResponse(jsonRequestId) );

            std::string jsonRpcName = jsonRequest.getMethodName();
            isOneway = jsonRequest.isNotification();

            RcfServer::JsonRpcMethod jsonRpcMethod;

            {
                ReadLock lock(mRcfServer.mStubMapMutex);
                RcfServer::JsonRpcMethods::iterator iter = mRcfServer.mJsonRpcMethods.find(jsonRpcName);
                if (iter != mRcfServer.mJsonRpcMethods.end())
                {
                    jsonRpcMethod = iter->second;
                }
            }

            if (jsonRpcMethod)
            {
                jsonRpcMethod(jsonRequest, *jsonResponsePtr);
            }
            else
            {
                std::string errMsg = "Unknown JSON-RPC method name: " + jsonRpcName;
                jsonResponsePtr->getJsonResponse()["error"] = errMsg;
            }
        }
        catch(...)
        {
            std::string errMsg;
            try
            {
                throw;
            }
            catch(const RCF::Exception & e)
            {
                errMsg = e.getErrorString();
            }
            catch(const std::exception & e)
            {
                errMsg = e.what();
            }
            catch(const std::string & jsonSpiritErrMsg)
            {
                errMsg = jsonSpiritErrMsg;
            }
            catch(...)
            {
                errMsg = "Caught C++ exception of unknown type.";
            }

            jsonResponsePtr.reset( new JsonRpcResponse(jsonRequestId) );
            jsonResponsePtr->getJsonResponse()["result"] = json_spirit::mValue();
            jsonResponsePtr->getJsonResponse()["error"] = errMsg;
        }

        setTlsRcfSessionPtr();

        if (isOneway)
        {
            onWriteCompleted();
        }
        else
        {
            json_spirit::mObject & obj = jsonResponsePtr->getJsonResponse();

            MemOstreamPtr osPtr = getObjectPool().getMemOstreamPtr();
            json_spirit::write_stream(json_spirit::mValue(obj), *osPtr, json_spirit::pretty_print);
            ByteBuffer buffer(osPtr->str(), static_cast<std::size_t>(osPtr->tellp()), osPtr);
            ThreadLocalCached< std::vector<ByteBuffer> > tlcByteBuffers;
            std::vector<ByteBuffer> & buffers = tlcByteBuffers.get();
            buffers.push_back(buffer);
            getSessionState().postWrite(buffers);
        }
    }