예제 #1
0
void TCPConnectProtocol::onRpc (const HostId & sender, const ConnectDetailsReply & reply, const ByteArray & content) {
	AsyncOp * op = getReadyAsyncOp (reply.id);
	if (!op) {
		Log (LogWarning) << LOGID << "Did not found op " << reply.id  << " (maybe timeouted)" << std::endl;
		return;
	}
	RequestOp * rop = static_cast <RequestOp *> (op);
	ConnectDetailsPtr ptrDetails = ConnectDetailsPtr (new ConnectDetails(reply));
	if (rop->cb){
		rop->cb (reply.error, reply);
	}
	delete rop;
}
예제 #2
0
void HttpConnectionManager::requestConnection (const Url & url, int timeOutMs, const RequestConnectionCallback & callback) {
	assert (callback);
	{
		// Check the pool
		PendingConnectionMap::iterator i = mPendingConnections.find(ConId(url.protocol(), url.host()));
		if (i != mPendingConnections.end()){
			while (!i->second.empty()){
				AsyncOpId id = i->second.front();
				i->second.pop_front();
				PendingConnectionOp * op;
				getReadyAsyncOp (id, PendingConnection, &op);
				mPendingConnectionsCount--;
				if (op) {
					Log (LogInfo) << LOGID << "Reusing connection to " << url.protocol() << "/" << url.host() << " id=" << op->id() << std::endl;
					xcall (abind(callback, NoError, op->connection));
					delete op;
					return;
				}
			}
			// not existant anymore
			mPendingConnections.erase (i);
		}
	}
	EstablishConnectionOp * op = new EstablishConnectionOp (regTimeOutMs (timeOutMs));

	const String & protocol = url.protocol();
	if (protocol != "http" && protocol != "https") {
		Log (LogWarning) << LOGID << "Unsupported protocol: " << protocol << std::endl;
		return xcall(abind(callback, error::NotSupported, HttpConnectionPtr()));
	}
	op->callback = callback;
	op->connection = HttpConnectionPtr (new HttpConnection());
	op->connection->host = url.host();
	op->connection->pureHost = url.pureHost();
	op->connection->protocol = url.protocol();
	TCPSocketPtr sock = TCPSocketPtr (new TCPSocket ());
	op->connection->channel = sock;
	op->setId(genFreeId());
	op->setState(EstablishConnectionOp::WaitTcpConnect);
	Error e = sock->connectToHost(url.pureHost(), url.port(), timeOutMs, abind(dMemFun(this, &HttpConnectionManager::onTcpConnect), op->id()));
	if (e) {
		delete op;
		return xcall (abind(callback, e, HttpConnectionPtr()));
	}
	addAsyncOp (op);
}
예제 #3
0
void HttpConnectionManager::onChannelChange (AsyncOpId id) {
	PendingConnectionOp * op;
	getReadyAsyncOp (id, PendingConnection, &op);
	if (!op) return;

	ByteArrayPtr all = op->connection->channel->read();
	if (all && !all->empty()){
		Log (LogInfo) << LOGID << "Recv in pending connection: " << *all << std::endl;
		op->connection->inputBuffer.append(*all);
	}

	Error e = op->connection->channel->error();
	if (e) {
		// adieu
		Log (LogInfo) << LOGID << "Closing channel to " << op->connection->host << " as channel reported error: " << toString (e) << std::endl;
		xcall (abind (&throwAway, op->connection));
		removeFromPendingConnections (op);
		delete op;
		return;
	}
	// data ready? nobody knows, add it again...
	addAsyncOp (op);
}