ASIOConnectAndHandshake::ASIOConnectAndHandshake(const MultiplexedSocketPtr &connection, const UUID&sharedUuid): mResolver(connection->getASIOService()), mConnection(connection), mFinishedCheckCount(connection->numSockets()), mHeaderUUID(sharedUuid) { }
void ASIOSocketWrapper::sendProtocolHeader(const MultiplexedSocketPtr&parentMultiSocket, const Address& address, const UUID&value, unsigned int numConnections) { // if (paerntMultiSocket->isZeroDelim()) { std::stringstream header; header << "GET /" << value.toString() << " HTTP/1.1\r\n"; header << "Upgrade: WebSocket\r\n"; header << "Connection: Upgrade\r\n"; std::string hostname=address.getHostName(); for (std::string::iterator hi=hostname.begin(),he=hostname.end(); hi!=he; ++hi) { *hi=std::tolower(*hi); } header << "Host: " << hostname; if (address.getService()!="80") header << ":" << address.getService(); header << "\r\n"; header << "Origin: " << address.getHostName() << "\r\n"; if (parentMultiSocket->getStreamType()!= TCPStream::RFC_6455) { header << "Sec-WebSocket-Key1: x!|6 j9 U 1 guf 36Y04 | 4\r\n"; header << "Sec-WebSocket-Key2: 3 59 2 E4 _11 x80 \r\n"; } else { header << "Sec-WebSocket-Version: 13\r\n"; header << "Sec-WebSocket-Key: MTIzNDU2Nzg5MGFiY2RlZg==\r\n"; } header << "Sec-WebSocket-Protocol: " << (parentMultiSocket->getStreamType()==TCPStream::BASE64_ZERODELIM?"wssst":"sst") << numConnections << "\r\n"; header << "\r\n"; if (parentMultiSocket->getStreamType()!= TCPStream::RFC_6455) { header << "abcdefgh"; } std::string finalHeader(header.str()); Chunk * headerData= new Chunk(finalHeader.begin(),finalHeader.end()); rawSend(parentMultiSocket,headerData,true); /* }else { UUID return_value=(parentMultiSocket->isZeroDelim()?massageUUID(UUID::random()):UUID::random()); Chunk *headerData=new Chunk(TCPStream::TcpSstHeaderSize); copyHeader(&*headerData->begin(),parentMultiSocket->isZeroDelim()?TCPStream::WEBSOCKET_STRING_PREFIX():TCPStream::STRING_PREFIX(),value,numConnections); rawSend(parentMultiSocket,headerData,true); } */ }
void ASIOSocketWrapper::bindFunctions(const MultiplexedSocketPtr&parent) { mStrand = parent->getStrand(); std::tr1::weak_ptr<MultiplexedSocket> weak_parent(parent); mSendManyDequeItems = mStrand->wrap( std::tr1::bind(&ASIOSocketWrapper::sendManyDequeItems, this, weak_parent, _1, _2 ) ); }
bool MultiplexedSocket::sendBytesNow(const MultiplexedSocketPtr& thus,const RawRequest&data, bool force) { TCPSSTLOG(this,"sendnow",&*data.data->begin(),data.data->size(),false); TCPSSTLOG(this,"sendnow","\n",1,false); static Stream::StreamID::Hasher hasher; if (data.originStream==Stream::StreamID()) { unsigned int socket_size=(unsigned int)thus->mSockets.size(); for(unsigned int i=1;i<socket_size;++i) { thus->mSockets[i].rawSend(thus,new Chunk(*data.data),true); } thus->mSockets[0].rawSend(thus,data.data,true); return true; }else { size_t whichStream=hasher(data.originStream)%thus->mSockets.size(); if (data.unordered) { whichStream=thus->leastBusyStream(whichStream); } if (data.unreliable==false||rand()/(float)RAND_MAX>thus->dropChance(data.data,whichStream)) { return thus->mSockets[whichStream].rawSend(thus,data.data,force); }else { return true; } } }
void ASIOSocketWrapper::sendServerProtocolHeader(const MultiplexedSocketPtr& thus, const std::string&origin, const std::string&host, const std::string&port, const std::string&resource_name, const std::string&subprotocol, const std::string& response) { std::stringstream header; header << "HTTP/1.1 101 Web Socket Protocol Handshake\r\n"; header << "Upgrade: WebSocket\r\n"; header << "Connection: Upgrade\r\n"; if (thus->getStreamType() == TCPStream::RFC_6455) { header << "Access-Control-Allow-Origin: " << origin << "\r\n"; header << "Location: ws://" << host << resource_name << "\r\n"; header << "Sec-WebSocket-Accept: " << response << "\r\n"; header << "Sec-WebSocket-Protocol: " << subprotocol << "\r\n"; header << "\r\n"; } else { header << "Sec-WebSocket-Origin: " << origin << "\r\n"; header << "Sec-WebSocket-Location: ws://" << host << resource_name << "\r\n"; header << "WebSocket-Protocol: " << subprotocol << "\r\n"; header << "\r\n"; header << response; } std::string finalHeader(header.str()); Chunk * headerData= new Chunk(finalHeader.begin(),finalHeader.end()); rawSend(thus,headerData,true); }
void ASIOConnectAndHandshake::connectToIPAddress(const ASIOConnectAndHandshakePtr& thus, const MultiplexedSocketPtr&connection, const Address& address, bool no_delay, unsigned int whichSocket, const tcp::resolver::iterator &it, const ErrorCode &error) { if (!connection) { return; } if (error) { if (it == tcp::resolver::iterator()) { //this checks if anyone else has failed if (thus->mFinishedCheckCount>=1) { //We're the first to fail, decrement until negative thus->mFinishedCheckCount-=connection->numSockets(); thus->mFinishedCheckCount-=1; connection->connectionFailedCallback(whichSocket,error); }else { //keep it negative, indicate one further failure thus->mFinishedCheckCount-=1; } }else { tcp::resolver::iterator nextIterator=it; ++nextIterator; connection->getASIOSocketWrapper(whichSocket).getSocket() .async_connect( *it, connection->getStrand()->wrap( boost::bind(&ASIOConnectAndHandshake::connectToIPAddress, thus, connection, address, no_delay, whichSocket, nextIterator, boost::asio::placeholders::error) ) ); } } else { connection->getASIOSocketWrapper(whichSocket) .sendProtocolHeader(connection, address, thus->mHeaderUUID, connection->numSockets()); Array<uint8,TCPStream::MaxWebSocketHeaderSize> *header=new Array<uint8,TCPStream::MaxWebSocketHeaderSize>; CheckWebSocketHeader headerCheck(header,true); boost::asio::async_read(connection->getASIOSocketWrapper(whichSocket).getSocket(), boost::asio::buffer(header->begin(),(int)TCPStream::MaxWebSocketHeaderSize>(int)ASIOReadBuffer::sBufferLength?(int)ASIOReadBuffer::sBufferLength:(int)TCPStream::MaxWebSocketHeaderSize), headerCheck, connection->getStrand()->wrap( boost::bind(&ASIOConnectAndHandshake::checkHeader, thus, connection, no_delay, whichSocket, header, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred) ) ); } }
void ASIOSocketWrapper::unpauseSendStreams(const MultiplexedSocketPtr&parentMultiSocket) { std::vector<Stream::StreamID> toUnpause; toUnpause.swap(mPausedSendStreams); parentMultiSocket->unpauseSendStreams(toUnpause); }