/* Chooses the appropriate connection, or opens a new one if necessary. Wraps xml in HTTP and sends. */ bool ConnBoshMultStat::sendRequest( const std::string& xml ) { ConnectionBase* conn = getConnection(); if( !conn ) return false; std::string request = "POST " + m_path; if( m_connMode == ModeLegacyHTTP ) { request += " HTTP/1.0\r\n"; request += "Connection: close\r\n"; } else request += " HTTP/1.1\r\n"; request += "Host: " + m_boshedHost + "\r\n"; request += "Content-Type: text/xml; charset=utf-8\r\n"; request += "Content-Length: " + util::int2string( xml.length() ) + "\r\n"; request += "User-Agent: gloox/" + GLOOX_VERSION + "\r\n\r\n"; request += xml; if( conn->send( request ) ) { m_lastRequestTime = time( 0 ); ++m_openRequests; return true; } // else // FIXME What to do in this case? // printf( "Error while trying to send on socket (state: %d)\n", conn->state() ); return false; }
ConnectionBase* ConnBoshMultStat::getConnection() { if( m_openRequests > 0 && m_openRequests >= m_maxOpenRequests ) { m_logInstance.warn( LogAreaClassConnectionBOSH, "Too many requests already open. Cannot send." ); return 0; } ConnectionBase* conn = 0; switch( m_connMode ) { case ModePipelining: if( !m_activeConnections.empty() ) { m_logInstance.dbg( LogAreaClassConnectionBOSH, "Using default connection for Pipelining." ); return m_activeConnections.front(); } else if( !m_connectionPool.empty() ) { m_logInstance.warn( LogAreaClassConnectionBOSH, "Pipelining selected, but no connection open. Opening one." ); return activateConnection(); } else m_logInstance.warn( LogAreaClassConnectionBOSH, "No available connections to pipeline on." ); break; case ModeLegacyHTTP: case ModePersistentHTTP: { if( !m_connectionPool.empty() ) { m_logInstance.dbg( LogAreaClassConnectionBOSH, "LegacyHTTP/PersistentHTTP selected, " "using connection from pool." ); return activateConnection(); } else if( !m_activeConnections.empty() ) { m_logInstance.dbg( LogAreaClassConnectionBOSH, "No connections in pool, creating a new one." ); conn = m_activeConnections.front()->newInstance(); conn->registerConnectionDataHandler( this ); m_connectionPool.push_back( conn ); conn->connect(); } else m_logInstance.warn( LogAreaClassConnectionBOSH, "No available connections to send on." ); break; } } return 0; }
ConnectionBase* ConnBoshMultStat::activateConnection() { ConnectionBase* conn = m_connectionPool.front(); m_connectionPool.pop_front(); if( conn->state() == StateConnected ) { m_activeConnections.push_back( conn ); return conn; } m_logInstance.dbg( LogAreaClassConnectionBOSH, "Connecting pooled connection." ); m_connectionPool.push_back( conn ); conn->connect(); return 0; }
ConnectionBase* SOCKS5BytestreamServer::getConnection( const std::string& hash ) { util::MutexGuard mg( m_mutex ); ConnectionMap::iterator it = m_connections.begin(); for( ; it != m_connections.end(); ++it ) { if( (*it).second.hash == hash ) { ConnectionBase* conn = (*it).first; conn->registerConnectionDataHandler( 0 ); m_connections.erase( it ); return conn; } } return 0; }
void ConnBoshMultStat::putConnection() { ConnectionBase* conn = m_activeConnections.front(); switch( m_connMode ) { case ModeLegacyHTTP: m_logInstance.dbg( LogAreaClassConnectionBOSH, "Disconnecting LegacyHTTP connection" ); conn->disconnect(); conn->cleanup(); // This is necessary m_activeConnections.pop_front(); m_connectionPool.push_back( conn ); break; case ModePersistentHTTP: m_logInstance.dbg( LogAreaClassConnectionBOSH, "Deactivating PersistentHTTP connection" ); m_activeConnections.pop_front(); m_connectionPool.push_back( conn ); break; case ModePipelining: m_logInstance.dbg( LogAreaClassConnectionBOSH, "Keeping Pipelining connection" ); default: break; } }
static void gotClientData(gpointer data, gint source, PurpleInputCondition cond) { ConnectionBase *connection = (ConnectionBase *) data; connection->recv(); }