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; }
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); } }
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; }